VS2019代码迁移遇C2280错误:已删除的operator<<重载问题求助
解决VS2019中basic_ostream输出LPCTSTR触发C2280错误的问题
问题原因
LPCTSTR在Unicode编译环境下等价于const wchar_t*,而你定义的ostream是基于char的窄字符流。VS2019开始明确删除了basic_ostream<char>与const wchar_t*的重载运算符,目的是避免隐式转换带来的乱码或未定义行为,这就是触发C2280(尝试调用已删除函数)的原因。遗留程序能正常运行是因为旧版VS允许这种不安全的隐式转换。
解决办法
方案1:统一使用宽字符流
如果项目采用Unicode字符集,直接改用宽字符版本的basic_ostream,匹配LPCTSTR的类型:
CStringArray asLine; using ostream = basic_ostream<wchar_t, char_traits<wchar_t>>; ostream os; os << (LPCTSTR)asLine[nLine2];
方案2:转换宽字符为窄字符输出
若必须使用窄字符流,需将LPCTSTR指向的宽字符串转换为窄字符后输出:
CStringArray asLine; using ostream = basic_ostream<char, char_traits<char>>; ostream os; CString strLine = asLine[nLine2]; CT2A szNarrow(strLine); // 需包含头文件<atlconv.h> os << szNarrow;
注意:转换过程中,若原字符串包含窄字符无法表示的Unicode字符,会出现乱码,需根据业务场景处理。
方案3:显式重载operator<<适配CString
在项目中添加针对CString的重载函数,避免直接强转LPCTSTR:
#include <ostream> #include <atlconv.h> template <class CharTraits> std::basic_ostream<char, CharTraits>& operator<<(std::basic_ostream<char, CharTraits>& os, const CString& str) { CT2A szNarrow(str); os << szNarrow; return os; } // 使用示例 os << asLine[nLine2]; // 无需强转,直接传入CString对象
替代方案(标准库转换方式)
如果不想依赖MFC的转换宏,可使用C++标准库的工具完成宽字符串到窄字符串的转换:
#include <ostream> #include <locale> #include <codecvt> #include <string> std::string wstring_to_string(const std::wstring& wstr) { std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; return converter.to_bytes(wstr); } // 调用示例 std::wstring wstr = asLine[nLine2]; os << wstring_to_string(wstr);
内容的提问来源于stack exchange,提问作者Madhu Rao
相关产品推荐
相关产品推荐

