我见过this nice code。并希望将其用于我的情况。
因此,我改变了方向,所以combine(f,g,h)(x)
的意思是:做h(g(f(x)))
。
但实际上我想要:
执行f(x)
。
如果结果为y
,则执行g(y)
,否则执行g()
。
如果结果为z
,则执行h(z)
,否则执行h()
。
所以这是更改后的代码:
template<typename ... Fs>
struct combine_impl
{
combine_impl(Fs&& ... fs) : functionTuple(std::forward<Fs>(fs) ...) {}
static constexpr numberOfFs = sizeof ... (Fs);
template<size_t N, typename ... Ts>
auto apply(std::integral_constant<size_t, N>, Ts&& ... ts) const
{
return apply( std::integral_constant<size_t, N + 1>{}
, std::get<N>(functionTuple)(std::forward<Ts>(ts)...));
}
template<typename ... Ts>
auto apply(std::integral_constant<size_t, numberOfFs -1>, Ts&& ... ts) const
{
return std::get<numberOfFs -1>(functionTuple)(std::forward<Ts>(ts)...);
}
template<typename ... Ts>
auto operator()(Ts&& ... ts) const
{
return apply(std::integral_constant<size_t,0>{}, std::forward<Ts>(ts) ...);
}
std::tuple<Fs ...> functionTuple;
};
template<typename ... Fs>
auto combine(Fs&& ... fs)
{
return combine_impl<Fs ...>(std::forward<Fs>(fs) ...);
}
编辑: 弄清楚问题是什么: 示例:
struct FunctorA
{
float operator()(int k) const {return k*2.5f;}
};
struct FunctorB
{
float operator()(float k) const {return k*2.5f;}
};
void main()
{
float result = combine(FunctorA(),FunctorB())(4);
}
使用该代码可以正常工作。 但我希望也能使用这样的代码:
struct FunctorA
{
voidoperator()(int k) const
{
// side effects
}
};
struct FunctorB
{
float operator()() const
{
return 42.f;
}
};
void main()
{
float result = combine(FunctorA(),FunctorB())(4);
}
由于invalid use of void expression
,因此无法编译。
编辑: 经过一番阅读:sfinae应该可以做到。 表达式
decltype(std::get<N>(functionTuple)(std::forward<Ts>(std::declval<Ts>())...))
当我需要使用其他版本的apply时,其类型为void。