在C++中如何区分ASCII字符值与普通数值?
C++区分字符字面量与数值及sum函数实现方案
核心判断逻辑
C++的编译期类型系统可以直接区分类似'A'和65的字面量类型:
- 字符字面量
'A'的原生类型为char - 整数字面量
65的原生类型为int
如果二者经过隐式转换统一变为double类型后,运行期无法从double值本身区分原始数据类型,因为转换后二者的存储值完全一致,没有额外的类型标识位。
sum函数实现
前提说明
如果直接将sum函数的入参声明为double类型,传入'A'时会在函数调用前就完成隐式转换得到65.0,函数内部无法区分来源。因此需要通过模板参数推导,在隐式转换发生前先完成入参类型校验,校验通过后再转double计算,既满足计算用double的要求,也能识别字符类型入参。
代码实现(入参类型一致版本)
#include <type_traits> template<typename T> double sum(T a, T b) { // 入参为字符类型直接返回0 if constexpr (std::is_same_v<std::decay_t<T>, char> || std::is_same_v<std::decay_t<T>, signed char> || std::is_same_v<std::decay_t<T>, unsigned char>) { return 0.0; } // 非字符类型转double求和 return static_cast<double>(a) + static_cast<double>(b); }
效果验证:
sum(10, 65):入参类型为int,返回结果为75.0,符合要求sum(10, 'A'):两个入参类型不一致,编译期直接报错,满足「入参类型一致」的约束sum('A', 'B'):入参类型为char,返回结果为0.0
代码实现(入参可不同类型版本)
如果不需要严格限制两个入参类型完全一致,只要求只要有一个入参是字符就返回0,可以用以下实现:
#include <type_traits> template<typename T1, typename T2> double sum(T1 a, T2 b) { // 任意一个入参为字符类型就返回0 if constexpr (std::is_same_v<std::decay_t<T1>, char> || std::is_same_v<std::decay_t<T1>, signed char> || std::is_same_v<std::decay_t<T1>, unsigned char> || std::is_same_v<std::decay_t<T2>, char> || std::is_same_v<std::decay_t<T2>, signed char> || std::is_same_v<std::decay_t<T2>, unsigned char>) { return 0.0; } return static_cast<double>(a) + static_cast<double>(b); }
效果验证:
sum(10, 65)返回75.0sum(10, 'A')返回0.0,符合要求
边界说明
如果要求sum函数的对外入参类型必须直接声明为double,不允许使用模板,该需求无法实现:char到double是C++标准允许的隐式转换,转换后'A'和65对应的double值完全相同,没有任何特征可以区分二者来源。
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

