2016-03-07 84 views
1

我有一个可调用类型的元组。从可调用元组的结果创建一个元组

std::tuple<std::function<int(int)>, std::function<std::string(double)>> funcs; 

我想创建一个具有每个调用的结果的另一种类型的元组。例如,funcs包含int->intdouble->std::string

如何创建一个元组results依赖于funcs每一个元素,它可能看起来是这样的。

std::tuple<int, std::string> results; 

回答

1
#include <tuple> 
#include <functional> 
#include <string> 


// takes an arbitrary tuple of std::functions and creates a 
// tuple of the return types of those std::functions 
template<class T, class... Types> 
struct TupleHandler; 

// handles the recursive inheritance base case when all the 
// elements of the tuple have been processed 
template<class... Types> 
    struct TupleHandler<std::tuple<>, Types...> { 
    using ReturnTypeTuple = std::tuple<Types...>; 
    }; 

// Strips off the first std::function in the tuple, determines 
// its return type and passes the remaining parts on to have the next element 
// processed 
template<class Return, class... Rest, class... Tail, class... Types> 
struct TupleHandler<std::tuple<std::function<Return(Rest...)>, Tail...>, Types...> : TupleHandler<std::tuple<Tail...>, Types..., Return> { 
    using ReturnTypeTuple = typename TupleHandler<std::tuple<Tail...>, Types..., Return>::ReturnTypeTuple; 
}; 

int main() 
{ 
    std::tuple<std::function<int(int)>, std::function<std::string(double)>> funcs; 

    // Of course for this simple use case you could have just used std::make_tuple, but it still demonstrates the solution 
    TupleHandler<decltype(funcs)>::ReturnTypeTuple return_value_tuple(std::get<0>(funcs)(1), std::get<1>(funcs)(4.4)); 

    // added per comment 
    auto x = [](auto funcs){ typename TupleHandler<decltype(funcs)>::ReturnTypeTuple results; }; 

} 
+0

这个作品,如果我知道funcs'到底是什么'。但它可能有某种'auto x = [](auto funcs){/ *在这里使用你的代码* /}' – nRewik

+0

这适用于任意的元组类型。 C++中每个变量的类型都是已知的,所以decltype(some_tuple_variable)总是会给出元组的类型。 – xaxxon

+0

这不起作用'auto x = [](auto funcs){TupleHandler :: ReturnTypeTuple结果; }' – nRewik

1

一种非递归的方式:

template <typename Func> struct result_of_function; 

template <typename Ret, typename ...Args> 
struct result_of_function<std::function<Ret(Args...)>> 
{ 
    using type = Ret; 
}; 

template <typename... Tuples> struct tuple_ret_function; 

template <typename... Funcs> 
struct tuple_ret_function<std::tuple<Funcs...>> 
{ 
    using type = std::tuple<typename result_of_function<Funcs>::type...>; 
}; 

Demo

1

std::function具有一个typedef称为result_type构件。只要使用它。

template<class... Funcs> 
auto tuple_function_ret_impl(std::tuple<Funcs...>) 
    -> std::tuple<typename Funcs::result_type ...>; 

template<class Tuple> 
using tuple_function_ret = decltype(tuple_function_ret_impl(Tuple())); 

Demo

using func_tuple = std::tuple<std::function<int(int)>, 
           std::function<std::string(double)>>; 

using ret_tuple = tuple_function_ret<func_tuple>; 
using ret_tuple = std::tuple<int, std::string>; // OK 
+0

这个版本更好。 – nRewik

+0

我不知道你可以在没有身体的情况下“调用”一个函数。这真是令人着迷。 – xaxxon