2013-10-02 61 views
1

对我来说,它看起来自然的编译器可以推断类型的模板是这样的:为什么编译器不能像模板<typename R(typename ... Args)>那样从模板中推导出类型?

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’

为什么这是不可能的? 什么是实现这种通用包装功能的方式?

感谢

回答

1

有建议做这样的事情在C++ 1Y,其状态我不是当前的。

对于这些提议,您的语法不正确,因为lambda是使用实例化std::function模板的错误类型。它需要签名,而不是某些lambda的类型。

写一个make_wrap是可能的,但需要采取lambda类型并自己提取args和返回值。这也不是一个好主意,因为如果你知道某种类型的唯一方法是从推论中扣除的,那么为什么类型会抹掉它?相反,请携带原始的lambda类型。

有理由想要这样做,但它们很少。

+0

你的论点在使用std :: function时是合法的。由于这个原因,我已经创建了一个更简单的包装类(http://pastebin.com/6RhFD3Wx),但是当我想用包装器实例化一个std ::函数作为其构造函数的参数时失败了。这就是为什么我想创建一个更好的包装,并提出了的想法。这在当前的C++中证明是错误的。对? – dennis90

+0

@ dennis90你在运算符上缺少'const',并且在那里有一个完美的向前和无限重载的'()'。我不知道那里还有什么不对。 – Yakk

+0

'const'只是因为这是一个概念的例证而丢失。如果没有nullary覆盖'()',我将无法调用不带参数的函数,转发不会编译。 – dennis90

相关问题