C++11 constexpr变量逻辑表达式

C++11 constexpr variadic logic expression

本文关键字:表达式 变量 constexpr C++11      更新时间:2023-10-16

我试图在编译时使用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>(), "!");
}

这是一个的实际示例