3 回答
TA贡献1793条经验 获得超6个赞
是的,这是可能的。一种做到这一点的方法(即使在最近的noexcept更改中也有效)是利用C ++ 11缩小转换规则:
甲缩小转换为一个整数型或无作用域枚举类型为整数类型不能表示原始类型的所有值的隐式转换[...],除非源是一个常量表达式,其值后积分优惠将适合进入目标类型。
(强调我的)。列表初始化通常不允许缩小转换范围,与SFINAE结合使用时,我们可以构建小工具来检测任意表达式是否为常量表达式:
// p() here could be anything
template<int (*p)()> std::true_type is_constexpr_impl(decltype(int{(p(), 0U)}));
template<int (*p)()> std::false_type is_constexpr_impl(...);
template<int (*p)()> using is_constexpr = decltype(is_constexpr_impl<p>(0));
constexpr int f() { return 0; }
int g() { return 0; }
static_assert(is_constexpr<f>());
static_assert(!is_constexpr<g>());
现场演示。
此处的关键是int{(expr, 0U)}包含从unsigned int到的变窄转换int(因此格式不正确),除非它 expr是一个常量表达式,在这种情况下,整个表达式(expr, 0U)都是一个常量表达式,其求值适合于type int。
- 3 回答
- 0 关注
- 493 浏览
添加回答
举报