适配std::string与std::wstring的trim模板函数编译报错求助
解决std::string/std::wstring通用trim模板的编译错误问题
你的问题核心在于预处理器无法处理模板参数的sizeof判断——预处理器在模板实例化之前就运行了,它根本不知道TCHAR是什么类型,更没法获取它的大小,所以#if (sizeof(TCHAR)==1)这种写法会直接触发C1017错误(无效的整数常量表达式)。
下面给你两种可行的解决方案,同时修复原代码里的一个小bug(substr的长度计算错误):
方案1:C++17及以上推荐用constexpr if
这种方式代码最简洁,编译期就能完成分支选择:
#include <string> #include <type_traits> template<typename TCHAR> std::basic_string<TCHAR> trim(const std::basic_string<TCHAR>& s) { // 编译期选择对应的空白字符序列 constexpr const TCHAR* whitespace = []() { if constexpr (std::is_same_v<TCHAR, char>) { return " \t\r\n"; } else if constexpr (std::is_same_v<TCHAR, wchar_t>) { return L" \t\r\n"; } else { // 对不支持的字符类型触发编译错误 static_assert(false, "trim only supports char or wchar_t"); } }(); // 用auto匹配basic_string的size_type(无符号类型,避免类型不匹配) auto ibegin = s.find_first_not_of(whitespace); if (ibegin == std::basic_string<TCHAR>::npos) { return {}; // 返回空字符串 } auto iend = s.find_last_not_of(whitespace); // 注意:substr的第二个参数是长度,需要+1,原代码漏掉了这一步 return s.substr(ibegin, iend - ibegin + 1); }
方案2:C11/C14兼容版(模板特化)
如果你的项目还在用C++17之前的标准,可以用模板特化来提供对应字符类型的空白序列:
#include <string> #include <type_traits> // 模板特化获取对应字符类型的空白字符 template<typename T> struct WhitespaceProvider; template<> struct WhitespaceProvider<char> { static constexpr const char* value = " \t\r\n"; }; template<> struct WhitespaceProvider<wchar_t> { static constexpr const wchar_t* value = L" \t\r\n"; }; template<typename TCHAR> std::basic_string<TCHAR> trim(const std::basic_string<TCHAR>& s) { constexpr const TCHAR* whitespace = WhitespaceProvider<TCHAR>::value; auto ibegin = s.find_first_not_of(whitespace); if (ibegin == std::basic_string<TCHAR>::npos) { return {}; } auto iend = s.find_last_not_of(whitespace); return s.substr(ibegin, iend - ibegin + 1); }
额外说明
- 原代码里用
int接收find_first_not_of的返回值是不安全的:std::basic_string的size_type是无符号类型(通常是size_t),用有符号的int可能会导致溢出或者类型匹配警告,改用auto或者std::basic_string<TCHAR>::size_type更规范。 - 原代码的
substr参数错误:substr(pos, length),而iend - ibegin是索引差,需要加1才能得到正确的子串长度,否则会漏掉最后一个非空白字符。
内容的提问来源于stack exchange,提问作者Zhang
相关产品推荐
相关产品推荐

