【问题标题】:Why can't compiler deduce types from templates like template<typename R(typename... Args)>?为什么编译器不能从 template<typename R(typename...Args)> 之类的模板中推断出类型?
【发布时间】:2019-04-21 18:32:00
【问题描述】:

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

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++ templates functor


    【解决方案1】:

    有人提议在 C++1y 中做这样的事情,我不了解它的状态。

    您的语法不适合这些建议,因为 lambda 是用于实例化 std::function 模板的错误类型。它需要一个签名,而不是某个 lambda 的类型。

    编写make_wrap 是可能的,但需要采用 lambda 类型并自己提取 args 和返回值。这也很少是一个好主意,因为如果您知道std::functions 类型的唯一方法是通过演绎,那么在这种情况下,为什么要键入擦除它?相反,请携带原始 lambda 类型。

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

    【讨论】:

    • 你关于 std::function 使用的论点是合法的。出于这个原因,我已经创建了一个更简单的包装类 (pastebin.com/6RhFD3Wx),但是当我想实例化一个 std::function 并将该包装作为其构造函数的参数时,它失败了。这就是为什么我想创建一个更好的包装器并提出 的想法。这在当前的 C++ 中被证明是错误的。对吗?
    • @dennis90 你在操作符上缺少const,并且在那里有一个完美的前向和无效的覆盖()。我不知道那里还有什么问题。
    • const 丢失只是因为这是一个概念的说明。如果没有空值覆盖 (),我将无法调用不带参数的函数,转发无法编译。
    • 有趣的是,我认为我的“转发未编译”参数完全无效。也许我忽略了一些东西......我现在正在研究一个真正有效的包装器并将其粘贴到这里。
    • @dennis90 “我不知道出了什么问题,但这里有一个例子,我理解是发生了什么,出了什么问题?”比较没用。 Simple, self contained, complete examples 如果您不要求他人读懂您的想法,则必须填写。
    猜你喜欢
    • 2012-03-26
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    相关资源
    最近更新 更多