如何编写可同时接收char*与const char*指针引用的C++函数
解决方案
方案1:使用函数模板自动推导指针类型(最推荐)
直接将函数改写为模板形式,编译器会自动根据入参的指针类型生成对应实例,无额外运行时开销,代码完全不需要重复编写:
template <typename CharT> uint16_t get_char_and_inc(CharT*& c) { uint16_t val = static_cast<uint8_t>(*c++); if ((val & 0xC0) == 0xC0) while ((*c & 0xC0) == 0x80) val = (val << 8) | static_cast<uint8_t>(*c++); return val; }
如果需要做类型校验避免传入非法指针类型,可以增加静态断言限制(C++11及以上支持):
#include <type_traits> template <typename CharT> uint16_t get_char_and_inc(CharT*& c) { static_assert(std::is_same<typename std::remove_cv<CharT>::type, char>::value, "Only char and const char pointers are allowed"); // 原有逻辑不变 uint16_t val = static_cast<uint8_t>(*c++); if ((val & 0xC0) == 0xC0) while ((*c & 0xC0) == 0x80) val = (val << 8) | static_cast<uint8_t>(*c++); return val; }
注:新增的static_cast<uint8_t>是为了避免char为有符号类型时出现符号扩展问题,不影响原有功能。
方案2:使用二级指针(无需模板)
如果不想用模板,也可以将入参改为二级指针,隐式转换允许char**转const char**,可以兼容两种输入类型:
uint16_t get_char_and_inc(const char** c) { uint16_t val = static_cast<uint8_t>(*(*c)++); if ((val & 0xC0) == 0xC0) while ((**c & 0xC0) == 0x80) val = (val << 8) | static_cast<uint8_t>(*(*c)++); return val; }
调用时需要传入指针的地址:
get_char_and_inc(&cc); get_char_and_inc(&c);
原报错原因说明
char*转const char*属于隐式类型转换,转换过程会生成临时的右值对象,而C++标准不允许临时右值绑定到非常量左值引用,因此会触发编译报错。使用模板时不需要做类型转换,直接匹配对应指针类型的引用,不会生成临时对象,自然可以编译通过。
内容的提问来源于stack exchange,提问作者marciot
相关产品推荐
相关产品推荐

