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

时间:2013-07-06 12:57:23

标签: c++ templates c++11 variadic-templates constexpr

我试图在编译时使用variadics模板测试某些propierties(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)

2 个答案:

答案 0 :(得分:3)

获取代码编译的最小变化是将第二个test_trait重载替换为:

template<typename T0, typename T1, typename... Others>
constexpr bool trait_test(){
  return T0::value&&trait_test<T1, Others...>();
}

表示1个参数与第一个匹配,2个或更多匹配第二个。

答案 1 :(得分:2)

确实这是模棱两可的。接受一个模板参数的函数模板并不比接受一个或多个模板参数的函数模板更专业,因为函数模板的部分排序是在 function 参数上完成的 - 并且两个函数模板都具有零函数参数。

如果我可以建议另一种方法:

#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>(), "!");
}

这是live example