C++自定义substring模板函数运行gtest时出现char转const char*编译错误
编译错误根因
模板函数的实例化是按需触发的,你遇到的报错来自两个叠加的问题:
- 参数推导错配:测试用例中传入的
"hello"、"hamburger"是字符串字面量,类型为const char[],传值给模板形参S时会发生数组退化,最终S被推导为const char*指针类型。此时函数内的语句S substr = string_[Istart]本质是把单个char值赋值给const char*类型的指针变量,属于不被允许的隐式类型转换,直接触发了报错。 - 初始化逻辑本身存在适配问题:就算解决了指针推导的问题,原代码的
S substr = string_[Istart]也不兼容std::string的构造规则——std::string不存在“用单个char直接隐式初始化”的构造函数,该写法在S被推导为std::string时同样会触发编译错误,只是因为指针场景下的错误先被编译器捕获,暂时没有暴露出来。
修复方案
- 第一步:修正模板函数的初始化逻辑,适配值语义字符串的构造规则。把原来直接拿单个字符赋值的写法,改成构造长度为1、内容为目标首字符的子串实例:
template <typename S> S substring(S string_, int Istart, int Iend) { // 适配std::string等支持(长度, 填充字符)构造的类型 S substr = S(1, string_[Istart]); for(int i = (Istart + 1); i < Iend; i++) { substr += string_[i]; } return substr; } - 第二步:避免模板参数被推导为裸指针类型。在测试调用时,把传入的字符串字面量显式构造为std::string实例,避免数组退化为
const char*:TEST(subStr, T1){ string str="he"; EXPECT_EQ(str,substring(string("hello"), 0, 2)); } TEST(subStr, T2){ string str="urge"; EXPECT_EQ(str,substring(string("hamburger"), 4, 8)); }
*如果确实需要兼容传入C风格裸指针字符串的场景,需要单独为裸指针类型做模板特化,处理堆内存分配、逐字符拷贝、添加字符串结束符的逻辑,避免裸指针场景下的类型错配。需要注意的是,这种场景下返回的堆内存指针需要调用方手动释放,存在内存泄漏风险,更推荐统一使用std::string作为字符串类型,减少模板的兼容负担。
内容的提问来源于stack exchange,提问作者Mahreen Athar
相关产品推荐
相关产品推荐

