猿问

在C ++ 11中is_constexpr是否可能?

是否可以基于C ++ 11表达式是否为C ++ 11中的常量表达式(即constexpr)来生成编译时布尔值?关于SO的几个问题与此相关,但是我在任何地方都看不到一个直接的答案。


眼眸繁星
浏览 494回答 3
3回答

摇曳的蔷薇

是的,这是可能的。一种做到这一点的方法(即使在最近的noexcept更改中也有效)是利用C ++ 11缩小转换规则:甲缩小转换为一个整数型或无作用域枚举类型为整数类型不能表示原始类型的所有值的隐式转换[...],除非源是一个常量表达式,其值后积分优惠将适合进入目标类型。(强调我的)。列表初始化通常不允许缩小转换范围,与SFINAE结合使用时,我们可以构建小工具来检测任意表达式是否为常量表达式:// p() here could be anythingtemplate<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。
随时随地看视频慕课网APP
我要回答