没问题。
template<bool b>
using kbool = std::integral_constant<bool, b>;
template<std::size_t max>
struct dispatch_bools {
template<std::size_t N, class F, class...Bools>
void operator()( std::array<bool, N> const& input, F&& continuation, Bools... )
{
if (input[max-1])
dispatch_bools<max-1>{}( input, continuation, kbool<true>{}, Bools{}... );
else
dispatch_bools<max-1>{}( input, continuation, kbool<false>{}, Bools{}... );
}
};
template<>
struct dispatch_bools<0> {
template<std::size_t N, class F, class...Bools>
void operator()( std::array<bool, N> const& input, F&& continuation, Bools... )
{
continuation( Bools{}... );
}
};
实例 http://coliru.stacked-crooked.com/a/a7b8d1b13e41898e.
So kbool
是一个变量,表示编译时常量布尔值。dispatch_bools
是一个辅助结构体,它有一个operator()
.
This operator()
需要一个运行时数组bool
s,并开始于max-1
继续产生最大 if/else 分支,每个分支递归调用dispatch_bools
又计算了一个编译时布尔值。
这会生成 2^max 代码;正是您不想编写的代码。
延续一直向下传递到底部递归(其中max=0
)。此时,所有编译时布尔值都已构建完毕——我们称之为continuation::operator()
将这些编译时布尔值作为函数参数传递。
希望continuation::operator()
是一个可以接受编译时布尔值的模板函数。如果是,则有 2^max 个实例,每个实例都有 2^max 种可能的真/假组合。
要使用它来解决您的问题c++14 /questions/tagged/c%2b%2b14你只需这样做:
std::array<bool, 3> bargs={{b0, b1, b2}};
dispatch_bools<3>{}(bargs, [&](auto...Bargs){
myFunc<decltype(Bargs)::value...,otherArgs>(args);
});
这很容易,因为c++14 /questions/tagged/c%2b%2b14 has auto
拉姆达;它可以有一个模板operator()
在 lambda 上。将这些编译时布尔参数转换回模板非类型参数很容易。
请注意,许多名义上c++11 /questions/tagged/c%2b%2b11编译器支持自动 lambda,因为它非常简单。但是,如果您缺少它,您仍然可以解决这个问题c++11 /questions/tagged/c%2b%2b11使用辅助结构:
template<class OtherArgs>
struct callMyFunc {
Args args;
template<class...Bools>
void operator()(Bools...){
myFunc<Bools::value...,otherArgs>(args);
}
};
现在使用的是:
std::array<bool, 3> bargs={{b0, b1, b2}};
dispatch_bools<3>{}(bargs, callMyFunc<otherArgs>{args});
这基本上是手动编写的c++14 /questions/tagged/c%2b%2b14lambda 就可以了。
In c++14 /questions/tagged/c%2b%2b14你可以替换void
with auto
并返回而不只是递归,它会很好地为您推断出返回类型。
如果你想要这个功能c++11 /questions/tagged/c%2b%2b11你可以写很多decltype
代码,或者你可以使用这个宏:
#define RETURNS(...) \
noexcept(noexcept(__VA_ARGS__)) \
-> decltype(__VA_ARGS__) \
{ return __VA_ARGS__; }
并写出正文dispatch_bools
like:
template<class T, std::size_t N, class F, class...Bools>
auto operator()( std::array<T, N> const& input, F&& continuation, Bools... )
RETURNS(
(input[max-1])?
dispatch_bools<max-1>{}( input, continutation, kbool<true>{}, Bools{}... )
:
dispatch_bools<max-1>{}( input, continutation, kbool<false>{}, Bools{}... )
)
和类似的<0>
专业化,并获得c++14 /questions/tagged/c%2b%2b14款式退货扣除c++11 /questions/tagged/c%2b%2b11.
RETURNS
使得推断单行函数的返回类型变得微不足道。