C++ Variadic模板AND和OR

nkn*_*ght 7 c++ variadic-templates c++11

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

template<bool...v> struct var_and { static bool constexpr value = /* ??? */; };
Run Code Online (Sandbox Code Playgroud)

所以在编译时var_and<v...>::value提供&&了布尔包v

你可以做同样struct var_or<v...>||

你能用短路评估(两种情况下)吗?

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

template<bool... v> constexpr bool var_and = (v && ...);
template<bool... v> constexpr bool var_or  = (v || ...);
Run Code Online (Sandbox Code Playgroud)

看来,对于基于参数包的方法,只能进行受限类型的"短路评估":在var_or<true,foo(),bar()>仅实例化一次调用||时,它也会调用两者foobar.

bam*_*s53 10

你不想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;
};
Run Code Online (Sandbox Code Playgroud)

显然可以做同样的事情||.

短路评估无关紧要,因为这只涉及不会产生任何副作用的常数表达式.

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

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;
};
Run Code Online (Sandbox Code Playgroud)

更新C++ 17:使用fold表达式可以简化这一过程.

template<bool...v> struct var_and {
    static constexpr bool value = (v && ...);
};
Run Code Online (Sandbox Code Playgroud)

或者使用模板变量作为enobayram建议:

template<bool... b> constexpr bool var_and = (b && ...);
Run Code Online (Sandbox Code Playgroud)

  • 如果左侧的评估结果是真的,那么"编译时评估器"永远不应该_evaluate_end && var_and <tail ...> :: value`的右侧,仍然会进行短路.但是编译器仍然需要构造表达式,这意味着生成类型`var_and <tail ...>`.由于计算是作为构造类型的一部分而不是作为评估"... :: value"表达式的一部分完成的,因此该方法实际上没有短路.但是我想我知道一种获得它的方法.我会编辑我的答案. (2认同)