C++11 constexpr变量逻辑表达式
C++11 constexpr variadic logic expression
我试图在编译时使用variadics模板来测试某些属性(type_trait),但以下代码似乎无法编译
template<typename test>
constexpr bool trait_test(){
return test::value;
}
template<typename test, typename... Others>
constexpr bool trait_test(){
return test::value&&trait_test<Others...>();
}
template<typename A, typename... Deriveds>
constexpr bool commonBaseClass{
return trait_test<std::is_base_of<A,Deriveds>...>();
}
问题似乎是,当"其他"的长度为0时,有2个可能的调用
trait_test<typename test>
trait_test<typename test, typename... Others={}>
编译器不知道该偷看哪一个。我当然想偷看第一个(并保持所有内容都是constexpr)
编译代码的最小更改是将第二个test_trait
重载替换为:
template<typename T0, typename T1, typename... Others>
constexpr bool trait_test(){
return T0::value&&trait_test<T1, Others...>();
}
这意味着1个参数仅与第一个匹配,2个或更多个与第二个匹配。
这确实是模棱两可的。接受一个模板实参的函数模板并不比接受一个或多个模板实参数的函数模板更专业,因为函数模板的部分排序是在函数实参上完成的,并且两个函数模板都没有函数实参。
如果我可以建议一种替代方法:
#include <type_traits>
template<typename... Ts>
struct all_of;
template<typename T>
struct all_of<T> : std::integral_constant<bool, T::value> { };
template<typename T, typename... Ts>
struct all_of<T, Ts...> : std::integral_constant<bool,
T::value && all_of<Ts...>::value> { };
template<typename A, typename... Deriveds>
constexpr bool commonBaseClass()
{
return all_of<std::is_base_of<A, Deriveds>...>();
}
然后,您可以这样使用commonBaseClass()
:
struct X { };
struct Y : X { };
struct Z : X { };
int main()
{
static_assert(commonBaseClass<X, Y, Z>(), "!");
}
这是一个的实际示例。
相关文章:
- 错误:constexpr 变量'struct2Var'必须由常量表达式初始化
- std::cout 在打印变量与函数表达式时的行为不同
- 如何在 lambda 表达式中传递变量?
- 表达式必须具有常数值,变量不能用作定义数组大小的常数
- C++ 在方程中使用变量;错误:表达式必须具有整数或无作用域枚举类型及其他
- 代码样式:在 switch/if 语句的分支中重用控件表达式或控制变量
- 编译器在传递 const 变量时返回错误:模板参数不是常量表达式
- C++ 使用变量而不是常量表达式初始化数组
- lambda 表达式中引用捕获的 constexpr 变量和非显式捕获的 constexpr 变量之间的区别
- 如何从字符串变量为正则表达式构建原始字符串
- 变量在常量表达式中可用的条件
- QT连接:使用lambda表达式重置通过了int变量(怪异)
- 通过引用传递表达式与通过引用传递变量
- 错误!Constexpr变量必须通过常数表达式constexpr初始化
- 没有变量声明为函数,但错误:二进制表达式的操作数无效
- 常量表达式中引用类型的变量
- 如何将表达式转换为变量
- 从C++调用 Python 或 Lua 来计算表达式,仅在需要时计算未知变量
- ExprTK 未知变量分辨率取决于表达式类型
- C lambda表达式变量