Make variadic function which takes arbitary functors and returns a tuple of each return value of input functors

a 夏天 提交于 2019-12-11 10:10:14

问题


I want to make a function object which takes arbitrary function objects and returns a tuple which stores the return value of each function object.

To achieve this goal, I made a class A

class A
{
private:
    template <class Ret, class Func>
    auto impl(Ret ret, Func func) -> decltype(tuple_cat(ret, make_tuple(func())))
    {
        return tuple_cat(ret, make_tuple(func()));
    }

    template <class Ret, class First, class... Funcs>
    auto impl(Ret ret, First first, Funcs... funcs) 
    -> decltype(impl(tuple_cat(ret, make_tuple(first())), funcs...))
    {
    return impl(tuple_cat(ret, make_tuple(first())), funcs...);
    }

public:
    template <class Func>
    auto operator()(Func func) -> decltype(make_tuple(func()))
        {
        return make_tuple(func());
    }

    template <class First, class... Funcs>
    auto operator()(First first, Funcs... funcs)
     -> decltype(impl(make_tuple(first()),funcs...))
    {
        impl(make_tuple(first()),funcs...);
    }
};

And in the main function, I made three lambdas.

int main(){
    auto func1 = [](){ cout << 1 << endl; return 1;};
    auto func2 = [](){ cout << 2 << endl; return 2;};
    auto func3 = [](){ cout << 3 << endl; return 3;};

    A a;
    auto x = a(func1, func2);
    cout << "ans : " << get<0>(x) << get<1>(x) << endl; // I expect ans : 12
}

This code can be compiled by gcc 4.7.2. However, it doesn't work as I expected. How should I modify this code?


回答1:


I think the problem is that you're missing a return statement:

template <class First, class... Funcs>
auto operator()(First first, Funcs... funcs)
 -> decltype(impl(make_tuple(first()),funcs...))
{
    return impl(make_tuple(first()),funcs...);
//  ^^^^^^
}

Without it, your code has Undefined Behavior. Per Paragraph 6.6.3/2 of the C++11 Standard:

[...] Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.




回答2:


The obvious problem is that you've a missing return statement as pointed out by other answer.

Anyway, I think you have done too much. This should work:

class A
{
public:
    template <class First, class... Funcs>
    auto operator()(First first, Funcs... funcs) -> decltype((make_tuple(first(),funcs()...)))
    {
        return (make_tuple(first(),funcs()...));
    }
};

int main(){
    auto func1 = [](){ cout << 1 << endl; return 1;};
    auto func2 = [](){ cout << 2 << endl; return 2;};

    A a;
    auto x = a(func1, func2);
    cout << "ans : " << get<0>(x) << get<1>(x) << endl; // I expect ans : 12
}

Online Demo




回答3:


@Andy's fix works, but you can do it a lot simpler than that, without implementing overloads nor helper functions:

#include <iostream>
#include <tuple>

template<typename... Args>
auto tuple_from_funs(Args&&... args) -> std::tuple<decltype(args())...>{
    return std::make_tuple(args()...);
}

int f() { return 1; }
char g() { return '2'; }
std::string h() { return "jorge"; }

int main() {
    auto tup = tuple_from_funs(f, g, h);
    std::cout << std::get<0>(tup) << ", " << std::get<1>(tup) << ", " << std::get<2>(tup) << std::endl;
}

Demo here.



来源:https://stackoverflow.com/questions/15059250/make-variadic-function-which-takes-arbitary-functors-and-returns-a-tuple-of-each

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!