C++ const char匹配报错原因及不修改const_str的解决方案
报错原因
这个看起来完全反常识的could not match 'const char' against 'const char'提示,纯粹是编译器报错信息写得糟糕,根本不是两个const char类型真的不匹配,核心问题是数组长度信息在模板推导阶段丢失,没法满足构造函数的模板参数推导要求:
- 你写的
char_sequence里,静态成员c_str的声明是static constexpr const Char c_str[] = {Cs..., 0};,没有显式写数组长度,属于不完整数组类型,长度只靠后面的初始化器隐式推导。 const_str的构造函数是模板,要求传入一个定长的const char数组引用const char (&arr)[N],需要从实参里推导出长度N。但你在模板函数call_lib里通过形参url访问这个依赖模板参数的静态成员时,编译器在推导阶段拿不到这个数组的明确长度,自然匹配不上对应的构造函数。- 编译器打报错日志的时候偷懒,没把数组长度不匹配的信息打出来,只打印了两边的元素类型
const char,才会出现相同类型没法匹配的离谱提示。报错里提到的const char const[]类型,就是编译器给不完整数组加上顶层const修饰后的结果,进一步误导了判断。
解决方案
完全不需要修改第三方库的const_str定义,两种改法任选其一即可:
- 修正
char_sequence的静态成员声明,显式给数组指定长度,这是最一劳永逸的改法:
template<typename Char, Char... Cs> struct char_sequence { // 显式指定长度为字符包长度+1,给末尾的'\0'留位置 static constexpr const Char c_str[sizeof...(Cs) + 1] = {Cs..., 0}; }; // 字面量运算符不需要改动 template<typename Char, Char... Cs> constexpr auto operator"" _cs() -> char_sequence<Char, Cs...> { return {}; }
- 如果不想改动原有
char_sequence的定义,可以在调用点直接通过类型访问静态成员,避免通过实例访问导致的类型信息丢失,注意需要提前引入<type_traits>头文件:
template<char... Cs> void call_lib(char_sequence<char, Cs...> url){ // 直接拿到url的原始类型,通过类型访问静态c_str成员,编译器可以正确识别数组长度 const_str(std::remove_cvref_t<decltype(url)>::c_str); }
内容的提问来源于stack exchange,提问作者ATK
相关产品推荐
相关产品推荐

