我不认为这是在做你想做的任何直接的方式,但这里是我在我的代码一些地方使用C++ 11的技术。其基本思想是利用我已经叫call_on_tuple
采取函数参数f
以及进一步的参数的元组的模板功能,展开元组和调用的函数的参数的扩展列表上:
template <typename Fun, typename... Args, unsigned... Is>
typename std::result_of<Fun(Args...)>::type
call_on_tuple(Fun&& f, std::tuple<Args...>&& tup, indices<Is...>)
{ return f(std::get<Is>(tup)...); }
这样的想法是不是调用
length(arguments());
你会打电话
call_on_tuple(length,arguments());
这假定arguments()
是陈因此它返回一个std::tuple<int,int,int>
(这基本上是你引用的问题的想法)。
现在困难的部分是如何获得Is...
参数包,这是一组整数0,1,2,...
用于对元组的元素进行编号。
如果你确定你总是会有三个参数,你可以直接使用0,1,2
,但是如果这个野心是为了使它适用于任何n元函数,我们需要另一个技巧,例如在this post的几个答案中。
这是一招变换参数的个数,即sizeof...(Args)
成整数0,1,...,sizeof...(Args)
的列表:
我就把这一招和call_on_tuple
在命名空间detail
实现:
namespace detail {
template <unsigned... Is>
struct indices
{ };
template <unsigned N, unsigned... Is>
struct index_maker : index_maker<N-1,N-1,Is...>
{ };
template <unsigned... Is>
struct index_maker<0,Is...>
{ typedef indices<Is...> type; };
template <typename Fun, typename... Args, unsigned... Is>
typename std::enable_if<!std::is_void<typename std::result_of<Fun(Args...)>::type>::value,
typename std::result_of<Fun(Args...)>::type>::type
call_on_tuple(Fun&& f, std::tuple<Args...>&& tup, indices<Is...>)
{ return f(std::get<Is>(tup)...); }
}
现在实际功能call_on_tuple
在全局名称空间中定义,如下所示:
template <typename Fun, typename... Args>
typename std::enable_if<!std::is_void<typename std::result_of<Fun(Args...)>::type>::value,
typename std::result_of<Fun(Args...)>::type>::type
call_on_tuple(Fun&& f, std::tuple<Args...>&& tup)
{
using std::tuple;
using std::forward;
using detail::index_maker;
return detail::call_on_tuple
(forward<Fun>(f),forward<tuple<Args...>>(tup),typename index_maker<sizeof...(Args)>::type());
}
它基本上调用detail::index_maker
来生成递增整数的列表,然后用那个调用detail::call_on_tuple
。
其结果是,你可以这样做:
int length(int x, int y, int z)
{ return x + y + z; }
std::tuple<int,int,int> arguments()
{ return std::tuple<int,int,int> { 1 , 2 , 3 }; }
int main()
{
std::cout << call_on_tuple(length,arguments()) << std::endl;
return 0;
}
是希望足够接近你需要的东西。
注意。我还添加了一个enable_if
以确保仅用于实际返回值的函数f
。您可以轻松地为返回void
的函数制作另一个实现。
抱歉再次提前关闭您的问题。
PS。您需要添加以下包含语句来测试此:
#include <tuple>
#include <type_traits>
#include <iostream>
每个问题都是重复这些天。 。 。 – Mob
有人downvoted没有评论,无论如何,你可以使用对象或结构来做到这一点 – vels4j
@jogojapan是的,你是正确的。 – vels4j