Templates C++;-检查所有模板参数是否为2的幂

Templates C++;-检查所有模板参数是否为2的幂,templates,c++11,constexpr,variadic,Templates,C++11,Constexpr,Variadic,我试图找到一种简单的方法来检查作为模板参数传递的参数是否都是2的幂。我在网站上发现了一个bithack,我有: constexpr bool isPowerOf2(size_t value){ return !(value == 0) && !(value & (value - 1)); } 这对单个值很有效,但将其应用于多个参数看起来很糟糕 static_assert(isPowerOf2(Arg1), "Argument must be a power of 2")

我试图找到一种简单的方法来检查作为模板参数传递的参数是否都是2的幂。我在网站上发现了一个bithack,我有:

constexpr bool isPowerOf2(size_t value){
return !(value == 0) && !(value & (value - 1));
}
这对单个值很有效,但将其应用于多个参数看起来很糟糕

static_assert(isPowerOf2(Arg1), "Argument must be a power of 2");
static_assert(isPowerOf2(Arg2), "Argument must be a power of 2");
static_assert(isPowerOf2(Arg3), "Argument must be a power of 2");

如果我能让它看起来像arePowersOf2(Arg1、Arg2、Arg3),那就更好了,但我在模板魔法方面还不是很先进。所以我的问题是:有没有简单的方法?我更喜欢constexpr C++11解决方案。

您可以编写一个
连接
特征,用于检查参数包中的所有
bool
是否为
true
。本例使用了的
bool\u pack
技巧:

template <bool...> struct bool_pack{};
template <bool... bools> 
struct conjunction : std::is_same<bool_pack<true, bools...>,
                                  bool_pack<bools..., true>>
{};

template <size_t... Args>
constexpr bool arePowerOf2() {
    return conjunction<isPowerOf2(Args)...>::value;   
}
template struct bool_pack{};
模板
结构连接:std::是否相同
{};
模板
constexpr bool arepower2(){
返回连接::值;
}
那么你可以这样称呼它:

arePowerOf2<Args...>();
arePowerOf2<Arg1, Arg2, Arg3>();
arePowerOf2


在C++1z中,您可以使用:

template <size_t... Args>
constexpr bool arePowerOf2() {
    return (... && isPowerOf2(Args));
}
模板
constexpr bool arepower2(){
返回(…&&ispowerrof2(Args));
}


C++1z也将获得,这与上面的版本略有不同。

一组布尔值是布尔值的整数序列:

template<bool...Bs>using bools = std::integer_sequence<bool, Bs...>;
这给了你:

static_assert(
  std::is_same<
    bools<isPowerOf2(Args)...>,
    make_trues_for_t<Args...>
  >::value, "Argument must be a power of 2"
);
static\u断言(
std::是一样的吗<
布尔斯,
使你成为现实
>::值,“参数必须是2的幂”
);

模板
constexpr std::是否相同<
布尔斯,
成真
>
_2(){return{};}的所有_幂_
在我看来,当我知道类型计算级别的答案时,我甚至喜欢从
constexpr
函数返回类型


作为奖励,失败的比较更清楚地表明了其目的,而不是一个一个的黑客攻击。
是相同的
将一系列的
进行比较,与一个黑客将
进行比较的off进行比较。在第一种情况下,从类型中可以清楚地看出哪里出了问题--
false
--特别是当您发现右侧总是一组只有
true

的函数时,您的函数不是模板,参数也不是模板参数。您可以使用C++1z吗?这很可爱!C++1z提供了非常简单的解决方案,但不幸的是,我仅限于使用C++0x。但是你的魔术对我很管用。谢谢你。
bool_pack
one是一个很好的选择p@Yakk这是一个非常华丽的黑客。
static_assert(
  std::is_same<
    bools<isPowerOf2(Args)...>,
    make_trues_for_t<Args...>
  >::value, "Argument must be a power of 2"
);
template<class...Args>
constexpr std::is_same<
    bools<isPowerOf2(Args)...>,
    make_trues<sizeof...(Args)>
  >
all_power_of_2() { return {}; }