8

你可以使用 C++11 可变参数模板来完成/* ??? */

template<bool...v> struct var_and { static bool constexpr value = /* ??? */; };

这样就在编译时var_and<v...>::value提供&&了布尔包?v

你可以为struct var_or<v...>for做同样的事情||吗?

您可以使用短路评估(在这两种情况下)吗?

编辑:对已接受答案的更新添加了 C++17折叠表达式启用

template<bool... v> constexpr bool var_and = (v && ...);
template<bool... v> constexpr bool var_or  = (v || ...);

似乎,对于基于参数包的方法,只有一种受限类型的“短路评估”是可能的:虽然var_or<true,foo(),bar()>只实例化一次调用||,但它也同时调用foobar

4

2 回答 2

11

您不想value成为 typedef。

template<bool head, bool... tail>
struct var_and {
    static constexpr bool value = head && var_and<tail...>::value;
};

template<bool b> struct var_and<b> {
    static constexpr bool value = b;
};

显然同样可以为||.

短路评估无关紧要,因为这只处理不会有任何副作用的常量表达式。

这是另一种方法,一旦发现错误值就停止递归生成类型,模拟一种短路:

template<bool head, bool... tail>
struct var_and { static constexpr bool value = false; };

template<bool... tail> struct var_and<true,tail...> {
    static constexpr bool value = var_and<tail...>::value;
};

template<> struct var_and<true> {
    static constexpr bool value = true;
};

C++17 更新:使用折叠表达式使这更简单。

template<bool...v> struct var_and {
    static constexpr bool value = (v && ...);
};

或者也使用 enobayram 建议的模板变量:

template<bool... b> constexpr bool var_and = (b && ...);
于 2012-08-09T22:20:03.517 回答
4

我只需要类似的东西,但我可以使用 C++14,所以我最终选择了以下内容,这可能比公认的答案更快(编译):

template <size_t N>
constexpr bool and_all(const bool (&bs) [N]) {
  for(bool b: bs) if(!b) return false;
  return true;
}

现在,这是 constexpr,因此它可以在编译时上下文和运行时使用。所以我们可以,例如,在这样的上下文中使用它some_struct<and_all({true, false, arg_pack...})>

于 2016-08-18T14:21:50.860 回答