Can you use C++11 variadic templates to complete /* ??? */
in:
你能使用c++ 11变量模板来完成/*吗?* /:
template<bool...v> struct var_and { static bool constexpr value = /* ??? */; };
so that var_and<v...>::value
provides &&
over the boolean pack v
at compile-time?
所以var_and < v…:value在编译时提供&& /布尔包v吗?
Can you do the same for struct var_or<v...>
for ||
?
你能对struct var_or
Can you use short-circuit evaluation (in both cases)?
你能使用短路评估(在两种情况下)吗?
Edit: An update to the accepted answer added that C++17 fold expressions enable
编辑:对已接受答案的更新,添加了c++ 17折叠表达式
template<bool... v> constexpr bool var_and = (v && ...);
template<bool... v> constexpr bool var_or = (v || ...);
It seems that, for parameter pack-based approaches, only a restricted type of "short-circuit evaluation" is possible: while instantiating var_or<true,foo(),bar()>
only calls ||
once, it also calls both foo
and bar
.
对于基于参数包的方法,似乎只有一种限制类型的“短路评估”是可能的:当实例化var_or
2 个解决方案
#1
10
You don't want value
to be a 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;
};
Obviously the same can be done for ||
.
显然||也可以这样做。
Short circuit evaluation doesn't matter because this only deals with constant expressions which won't have any side effects.
短路评估无关紧要,因为它只处理不会产生任何副作用的常量表达式。
Here's another method which stops recursively generating types as soon as it find a false value, emulating a kind of short circuiting:
这是另一种方法,一旦发现一个假值就停止递归生成类型,模拟一种短路:
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;
};
Update for C++17: Using a fold expression makes this much simpler.
对c++ 17的更新:使用一个折叠表达式使这个更简单。
template<bool...v> struct var_and {
static constexpr bool value = (v && ...);
};
Or also using a template variable as enobayram suggests:
或者也可以像enobayram建议的那样使用模板变量:
template<bool... b> constexpr bool var_and = (b && ...);
#2
3
I just needed something similar, but I have the luxury of using C++14, so I've ended up going with the following, which is probably faster (to compile) than the accepted answer:
我只是需要一些类似的东西,但是我有使用c++ 14的特权,所以我最后使用了下面的方法,这可能比被接受的答案更快(编译):
template <size_t N>
constexpr bool and_all(const bool (&bs) [N]) {
for(bool b: bs) if(!b) return false;
return true;
}
Now, this is constexpr, so it can be used in compile time contexts as well as runtime. So we can, for instance, use it in a context like some_struct<and_all({true, false, arg_pack...})>
现在,这是constexpr,因此它可以在编译时上下文中以及运行时中使用。例如,我们可以在some_struct
#1
10
You don't want value
to be a 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;
};
Obviously the same can be done for ||
.
显然||也可以这样做。
Short circuit evaluation doesn't matter because this only deals with constant expressions which won't have any side effects.
短路评估无关紧要,因为它只处理不会产生任何副作用的常量表达式。
Here's another method which stops recursively generating types as soon as it find a false value, emulating a kind of short circuiting:
这是另一种方法,一旦发现一个假值就停止递归生成类型,模拟一种短路:
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;
};
Update for C++17: Using a fold expression makes this much simpler.
对c++ 17的更新:使用一个折叠表达式使这个更简单。
template<bool...v> struct var_and {
static constexpr bool value = (v && ...);
};
Or also using a template variable as enobayram suggests:
或者也可以像enobayram建议的那样使用模板变量:
template<bool... b> constexpr bool var_and = (b && ...);
#2
3
I just needed something similar, but I have the luxury of using C++14, so I've ended up going with the following, which is probably faster (to compile) than the accepted answer:
我只是需要一些类似的东西,但是我有使用c++ 14的特权,所以我最后使用了下面的方法,这可能比被接受的答案更快(编译):
template <size_t N>
constexpr bool and_all(const bool (&bs) [N]) {
for(bool b: bs) if(!b) return false;
return true;
}
Now, this is constexpr, so it can be used in compile time contexts as well as runtime. So we can, for instance, use it in a context like some_struct<and_all({true, false, arg_pack...})>
现在,这是constexpr,因此它可以在编译时上下文中以及运行时中使用。例如,我们可以在some_struct