c++ - 为什么编译器不能从模板中推导出类型,例如 template<typename R(typename... Args)>?

标签 c++ templates functor

对我来说,编译器可以推导出这样的模板类型看起来很自然:

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/

相关文章:

C++仿函数,一种有效的方法?

C++ - 将对象(如字符串)映射到表中的成员函数的正确方法

c++ - 将 child map 存储在基类 vector 中

c++ - std::make_shared 在使用来自位域的参数构造时无法编译

c++ - 如何将c/c++回调函数转换为delphi

javascript - 在 AngularJS 中,如何使用指令创建具有更改变量名称的模板?

c++ - 从 ESP8266 Arduino 连接到我的服务器

c++ - 为什么 Visual Studio 不允许我在 enable_if 中使用模板化的 constexpr 函数?

c++ - 如何使我的迭代器类看起来不像容器类?

python - 闭包:什么是好的用例示例?为什么不是仿函数?它值得负面影响吗?