应用一组N个函数中的第一个有效函数 [英] Apply the first valid function of a set of N functions
问题描述
上一个答案显示了如何基于调用的有效性来应用功能:此处.但是,它适用于两个功能.我想知道是否可以使用C ++ 14中的智能模板编程技巧将这一概念推广到N
函数.
This previous answer shows how to apply function based on the validity of a call: here. However, it applies to two functions. I was wondering if the concept could be generalized to N
functions using smart template programming tricks, in C++14.
问题如下:
template <std::size_t N, class... X>
/* [Return type] */ apply_on_validity(X&&... x)
{
// Tricks here
}
// The function would be equivalent to a hypothetical
// template <std::size_t N, class... F, class... Args>
// [Return type] apply_on_validity(F&&... f, Args&&... args)
// where N = sizeof...(F) is the number of functions
在执行方面:
apply_on_validity<3>(f1, f2, f3, a, b, c, d, e);
会:
- 如果表达式有效,则调用
f1(a, b, c, d, e)
,否则 - 如果表达式有效,则调用
f2(a, b, c, d, e)
,否则 - 如果表达式有效,则调用
f3(a, b, c, d, e)
,否则 - 什么都不做
- call
f1(a, b, c, d, e)
if the expression is valid, otherwise - call
f2(a, b, c, d, e)
if the expression is valid, otherwise - call
f3(a, b, c, d, e)
if the expression is valid, otherwise - do nothing
在所有情况下,它都会返回已执行函数的结果.
And in all cases, it would return the result of the function that was executed.
在调用方,模板参数3
表示已指定的功能数.
On the calling side, the template parameter 3
indicates the number of functions that have been specified.
它在C ++ 14中可行吗?如果可以,怎么办?
Is it doable in C++14, and if so, how?
推荐答案
这里是踢球的另一个有趣之处,它滥用了超载分辨率.我们将把每个函数转换成带有rank
参数的另一个函数,将所有函数组合在一起,然后调用它们.选择会从过载集合中自然消失.
Here's another fun one for kicks, abusing overload resolution. We're going to transform each function into another function that takes a rank
argument, combine all of our functions together, and then just invoke them. The selection will just fall out naturally from the overload set.
我们的排名只是这种类型的阶梯:
Our ranker is just this ladder of types:
template <int I> struct rank : rank<I-1> { };
template <> struct rank<0> { };
我们需要一个功能转换器:
We need a function transformer:
template <class T, class F>
auto prepend_arg(F&& f) {
return [f=std::forward<F>(f)](T, auto&&... args)
-> decltype(std::forward<F>(f)(std::forward<decltype(args)>(args)...))
{
return std::forward<F>(f)(std::forward<decltype(args)>(args)...);
};
}
然后:
template <std::size_t N, std::size_t... Is, std::size_t... Js,
class... X>
decltype(auto) apply_impl(std::index_sequence<Is...>,
std::index_sequence<Js...>,
X&&... x)
{
auto all = std::forward_as_tuple(std::forward<X>(x)...);
return overload(
// all of our function cases
prepend_arg<rank<N-Is>>(std::get<Is>(all))...,
// base case: do nothing
[](rank<0>, auto&&...) {}
)(rank<N>{}, std::get<N+Js>(all)...);
// ^^^^^^^^^^^^^^^^^^^^^^^^
// pass in all the arguments
}
template <std::size_t N, class... X>
decltype(auto) apply_on_validity(X&&... x) {
return apply_impl<N>(
std::make_index_sequence<N>{},
std::make_index_sequence<sizeof...(X)-N>{},
std::forward<X>(x)...);
}
我将overload()
留作练习.
这篇关于应用一组N个函数中的第一个有效函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!