如何在C++14中模拟C++17的is_XXX_v类型特性变量?
如何在C14中模拟C17的is_XXX_v类型特性变量?
完全不需要大规模重写,你可以轻松模拟这些is_XXX_v变量——它们本质上就是C++14已存在的std::is_XXX<T>::value的语法糖。
具体实现方式
1. 逐个手动定义
针对每个需要的is_XXX_v,直接写对应的变量模板即可,示例如下:
// 模拟is_integral_v template <typename T> constexpr bool is_integral_v = std::is_integral<T>::value; // 模拟is_floating_point_v template <typename T> constexpr bool is_floating_point_v = std::is_floating_point<T>::value; // 模拟is_same_v(注意它是双参数的) template <typename T, typename U> constexpr bool is_same_v = std::is_same<T, U>::value;
把这些代码放在一个头文件里(比如cpp17_compat.h),然后在项目所有用到is_XXX_v的文件中include这个头文件,原来的调用代码完全不用改——比如原来写is_integral_v<int>,现在依然可以这么写。
2. 用宏批量生成(适合需要多个_v变量的场景)
如果项目里用到的is_XXX_v很多,重复写模板太麻烦,可以用宏批量定义:
#define DEFINE_TRAIT_V(trait) \ template <typename... Args> \ constexpr bool trait##_v = std::trait<Args...>::value; // 按需生成需要的变量: DEFINE_TRAIT_V(is_integral) DEFINE_TRAIT_V(is_floating_point) DEFINE_TRAIT_V(is_same) // 其他需要的比如is_pointer、is_reference等都可以这么加
注意事项
- 不要把这些定义加到
std命名空间里,这属于未定义行为。建议要么放在全局命名空间(如果原代码里的is_XXX_v没有加std::前缀),要么自己建一个兼容命名空间(比如namespace cpp17_compat),然后用using namespace cpp17_compat;导入。 - 确保你的C14编译器支持
constexpr变量——C14标准是支持的,所以特殊平台只要合规就没问题。
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

