【问题标题】:Auto is not allowed here for lambda class in header file头文件中的 lambda 类在此处不允许使用 Auto
【发布时间】:2020-10-07 12:39:36
【问题描述】:

我使用的是 c++14,自动在 .cpp 文件上运行良好,但是当我尝试在我的类中创建通用 lambda 时,它会生成错误“此处不允许使用自动”

我做错了什么?

代码:

class MyClass{
private:

    // Works
    std::function<void(MyClass&)> assign = [&](MyClass& other){
        //do something
    };

    // Does not work
    std::function<void(auto)> assign = [&](auto other){
        //do something
    };

    // Does not work
    auto assign = [&](auto other){
        //do something
    };
};

【问题讨论】:

标签: c++ c++14


【解决方案1】:

您的两次尝试都因不同的原因而失败。我们先看第二个:

auto assign = [&](auto other){
    //do something
};

这个可以在理论上起作用:lambda 表达式有一个可以推导出和使用的明确类型。但是,正如 this Q&A 中所述(对于 C++11 但仍然相关),该语言根本不允许 auto 成员变量,仅此而已。

您的第一次尝试因更多与设计相关的原因而失败。好吧,直接的问题是void(auto) 不是一个有效的类型(auto 是一个具有定制语义的句法关键字,而不是一个类型),但是一个可以可以想象使用一些标签类型来制作@ 987654326@ 一个有效的专业化。

然而,问题在于std::function 是一种类型擦除工具:它的目标是接收并隐藏一个函数体(例如您的 lambda),然后按需调用它。在进行调用时,functionoid 的类型已经不为人知,更不用说它潜在的operator() 模板了——处理一般情况需要在运行时为未知的参数类型实例化该模板,这是不可能的。

底线:存储 lambda 在概念上是有效的,但不支持其类型推导,并且类型擦除是该工作的错误工具,因为涉及模板。您唯一的解决方案是创建一个显式仿函数类,并将其用作成员:

class MyClass {
    struct {
        template <class T>
        void operator()(T other) const {
            // do something
        }
    } assign;
};

加分点:C++20 允许在未评估的上下文中使用 lambdas 和默认可构造的 lambdas,这意味着以下疯狂现在有效?

class MyClass {
    decltype([](auto other) {
        // do something
    }) assign;
};

【讨论】:

  • 清晰、简洁,回答了我所有的问题!谢谢,看到将 auto 作为成员类型的提议被拒绝的合理性非常有趣。不同的 c++ 版本有很多变化,有时会让人混淆哪个是哪个._.
【解决方案2】:

这些语句在不同的上下文/范围内完全可以:

void myfunc() {
    auto lambda = []() { };     // works fine
}

但是你所指的这里是一个类定义,没有明确的类型就不可能有成员。

class MyClass {
     
   std::function<void(MyClass&)> assign = lambda;
   // works, because there exists now a variable assign,
   // of specific type, which is initialised from a lambda

   auto kOne = 1;  // fails for the same reason
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 2011-03-30
    • 2018-05-15
    • 2023-03-04
    • 2014-05-28
    • 2012-01-30
    • 1970-01-01
    相关资源
    最近更新 更多