c++ - Extending std::to_string to support enums and pointers
问题描述
I have the following template function ToString
that uses std::to_string
for arithmetic types and tries doing a static_cast
for pointer and enum types.
#include <iostream>
#include <string>
template <typename T>
std::string ToString(T val)
{
if (std::is_arithmetic<T>::value)
{
return std::to_string(val);
}
if (std::is_enum<T>::value || std::is_pointer<T>::value)
{
return std::to_string(static_cast<size_t>(val));
}
}
enum class MyEnum : int
{
E1,
E2
};
int main(int argc, char* argv[])
{
MyEnum e = MyEnum::E1;
const void* ptr = &e;
std::cout << ToString(e) << std::endl;
std::cout << ToString(ptr) << std::endl;
}
The code above doesn't compile. Is there a way I can achieve the desired functionality?
The compilation errors on VS2017 are
Error C2440 'static_cast': cannot convert from 'T' to 'size_t'
Error C2665 'std::to_string': none of the 9 overloads could convert all the argument types
解决方案
你需要使用if constexpr
. 否则,您std::to_string
使用无法编译的指针或枚举实例化 (C2665)。
此外,您不能将指针静态转换为整数 (C2440)。你需要重新解释演员表。
此外,如果传递的参数既不是枚举、指针也不是算术类型,您的函数也没有返回值。在这种情况下,行为是未定义的。解决方案:总是返回一些东西(如果模板参数无效,则编译失败)。
此外,size_t
不保证足够大以表示所有指针值。你想要std::uintptr_t
。
而且您可能希望使用std::underlying_type_t
来获取正确的类型enum class
。
if constexpr (std::is_pointer<T>::value) {
return std::to_string(reinterpret_cast<std::uintptr_t>(val));
} else if constexpr (std::is_enum<T>::value)
{
return std::to_string(static_cast<std::underlying_type_t<T>>(val));
} else {
return std::to_string(val);
}
添加缺少的标题后,这应该可以工作。
PS 设计说明:现在打印指针、整数或枚举在输出中都是相同的。您可能想要添加一些前缀或类似的东西来消除结果的歧义。
推荐阅读
- android - Firebase分页回收器适配器给出错误?
- delphi-7 - Delphi 7 上的 TChromeTabs:选项卡中图像的错误渲染
- javascript - 使用 JS 从下拉列表中传递值
- python - 继承已经实例化的类
- linq - 从 linq 查询返回对象图
- java - 从属性计算实例数
- r - dplyr:在组中组合和过滤
- javascript - Chart.js v3.2 将雷达背景形状从多边形三角形更改为圆形
- julia - Julia - MLJ - 错误:UndefVarError:train_test_pair 未定义
- python - SettingWithCopyWarning:在本地机器上输出良好,在虚拟环境中出现奇怪的结果