我想创建一个函数对象,它接受任意函数对象并返回一个存储每个函数对象返回值的元组。
为实现这一目标,我制作了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...);
}
};
在主要功能中,我制作了三个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
}
此代码可以通过gcc 4.7.2编译。但是,它没有像我预期的那样工作。 我该如何修改此代码?
答案 0 :(得分:2)
我认为问题在于您错过了return
声明:
template <class First, class... Funcs>
auto operator()(First first, Funcs... funcs)
-> decltype(impl(make_tuple(first()),funcs...))
{
return impl(make_tuple(first()),funcs...);
// ^^^^^^
}
没有它,您的代码具有未定义的行为。根据C ++ 11标准的第6.6.3 / 2段:
[...]离开函数末尾相当于没有值的返回;这会导致值返回函数中的未定义行为。
答案 1 :(得分:1)
显而易见的问题是,如其他答案所指出的那样,你缺少一个返回语句。
无论如何,我认为你做得太多了。这应该有效:
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
}
答案 2 :(得分:1)
@Andy的修复工作正常,但你可以做很多比这更简单,而不实现重载和辅助函数:
#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;
}
演示here。