使用可变参数类型参数的变量函数
我不确定标准允许我尝试什么,甚至可能没有意义,所以通过一切手段随时纠正我。使用可变参数类型参数的变量函数
我试图将一个可变数量的std::function
对象传递给接受可变参数的函数,并接受可变参数模板参数。模板参数指定返回类型中进行传递的功能函数的签名看起来像这样:
template <typename ... TRets>
void DoStuff(std::function<TRets...()> funcs...)
什么我试图做的是从每个funcs
传入的传递返回值到另一个以扩展价值形式接受它们的函数。例如。 std::make_shared<TType>(funcs()...);
我正在使用g ++ 7.1.1和--std=c++17
标志,导致编译器发生故障。很明显,它不应该排除故障,但是标准中是否有上述代码无效的内容?或者,是否有不同的语法来完成这个目标?
为了完整起见,这里是一个最低限度的工作(对工作的一些定义)例如:
#include <functional>
#include <memory>
class MyClass {
public:
int m_a;
double m_b;
MyClass(int a, double b) : m_a(a), m_b(b) {};
};
template <typename TReturn, typename ... Args>
std::shared_ptr<TReturn> CallFunctions(std::function<Args...()> funcs...) {
// Do stuff here
return std::make_shared<TReturn>(funcs()...);
}
int main(int argc, char * argv[]) {
auto x = CallFunctions<MyClass, int, double>(
[]() { return 5; },
[]() { return 3.14; }
);
return 0;
}
编辑,以显示我原来的问题的更好的意图
template <class R, class... Args>
std::shared_ptr<R> CallFunctions(std::function<Args()>... funcs) {
return std::make_shared<R>(funcs()...);
}
这是C++ 11 。这是低效的。
template <class R, class... Args>
auto CallFunctions(Args&&... funcs)
-> decltype(std::make_shared<R>(funcs()...))
{
return std::make_shared<R>(funcs()...);
}
它删除不必要的类型擦除,并需要明确地传递返回类型。
如果你真的想通过返回类型:
template <class R, class... Args, class...Fs>
auto CallFunctions(Fs&&... funcs)
-> decltype(std::make_shared<R>(static_cast<Args>(funcs())...))
{
return std::make_shared<R>(static_cast<Args>(funcs())...);
}
,但我建议做上面的第二个解决方案。
这足够接近我需要的东西,请编辑C++ 17示例以使用'funcs()...'语法调用函数,我会接受。我编辑了原文,以更清楚地解释我的意图。 'CallFunctions'函数的主体然后变成'return std :: make_shared
@howard我不认为'funcs()...;'是有效的C++ 17;做了什么改变?啊,我明白了,编辑的问题。 – Yakk
我可以收集的最好的是,这个语法被参数包扩展所覆盖:'pattern ....'如[这里]概述的(http://en.cppreference.com/w/cpp/language/parameter_pack) – Howard
可以使用C++ 17 std::apply
在参数数据包的每个元素上使用std::invoke
。那么你不再需要std::function
了,因为std::invoke
只能调用可调用的对象,而且你不必再提供显式的模板参数(反正它是反模式)。作为奖励,你甚至可以检索被调用函数的返回值。
#include <functional>
#include <iostream>
#include <memory>
#include <tuple>
template < typename... R, typename... Args >
auto CallFunctions(Args... funcs) {
// Do stuff here
return std::apply(
[] (auto&&... x) {
return std::make_tuple(std::make_shared<R>(std::invoke(x))...);
}, std::make_tuple(funcs...)
);
}
int main() {
auto r = CallFunctions<int,double>(
[]() { return 5; },
[]() { return 3.14; }
);
std::cout << *std::get<0>(r) << ' ' << *std::get<1>(r) << '\n';
return 0;
}
你到底想干什么? – Justin
如果编译器出现故障,您可能需要提交错误报告。 – Justin
您是否期望每个传递给'CallFunctions'的函数都不带任何参数并返回一个值? – Justin