对我来说,编译器可以推导出这样的模板类型看起来很自然:
template<typename R(typename... Args)>
struct wrap {
std::function<R(Args)> func_;
template<typename... Args2>
wrap(Args2&& ...args2) : func_(std::forward<Args2>(args2)...) {
}
R operator()(Args&&... args) {
cout << "Extra stuff that wrap template does" << endl;
return func_(std::forward<Args>(args)...);
}
}
所以我可以用任何函数实例化而无需显式地将其签名提供给模板:
wrap w([](int x){ return 2*x });
轻松调用它:
w(3);
但事实证明,这种包裹根本行不通。 GCC 4.8.1 说 expected nested-name-specifier before ‘R’
。
为什么这是不可能的?实现这种通用包装功能的方法是什么?
最佳答案
有人提议在 C++1y 中做这样的事情,我目前不了解它的状态。
你的语法不适合那些提案,因为 lambda 是错误的类型来实例化 std::function
模板。它需要一个签名,而不是某些 lambda 的类型。
编写make_wrap
是可能的,但需要采用 lambda 类型并自行提取 args 和返回值。这也很少是一个好主意,因为如果你知道 std::function
类型的唯一方法是从演绎中,那么在那种情况下为什么要类型删除它?相反,随身携带原始 lambda 类型。
有理由想要这样做,但很少是好的。
关于c++ - 为什么编译器不能从模板中推导出类型,例如 template<typename R(typename... Args)>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19134558/