【问题标题】:What are lookup rules when calling function from lambda?从 lambda 调用函数时的查找规则是什么?
【发布时间】:2011-12-11 06:47:31
【问题描述】:

下面的例子演示了我在VC++ 2010中遇到的问题:

class Foo
{
    template<class T>
    static T foo(T t) { return t; }

public:
    void test()
    {
        auto lambda = []() { return foo(1); }; // call to Foo::foo<int>
        lambda();
    }
};

VC++ 产生:error C3861: 'foo': identifier not found

如果我限定了对 foo:Foo::foo(1); 的调用,那么这个示例编译时会出现警告: 警告 C4573:'Foo::foo' 的使用要求编译器捕获 'this',但当前默认捕获模式不允许

标准对这个案例有什么看法?是否应该找到不合格的名称?限定名称是否需要捕获this

【问题讨论】:

  • 嗯,这很奇怪。它是静态的,因此不需要this。我怀疑这是编译器错误,没有找到它是编译器认为它需要this 才能使用它的副作用。
  • g++ 也会发生这种情况,所以它看起来不像是一个错误。如果将其更改为 [&]() 而不是 []() 则编译正常,但这是因为它通过引用获取 this。
  • 话说another thread 说这是一个错误。

标签: c++ c++11


【解决方案1】:

Microsoft 已在多个案例中看到此问题的报告。见:

Scope Resolution with lambdas interferes with namespace and type resolution

Template resolution in lambdas

正如您所发现的,显式解析允许它找到名称。还有一个关于这个的额外警告,这也是一个编译器错误(名称解析不需要访问它,尽管我可以看到编译器实现可能需要它) - 虽然它是一个单独的错误。 Microsoft 已确认这是一个错误,并且显然已为下一个版本准备了修复程序。

【讨论】:

    【解决方案2】:

    以下编译正常。在我看来,这一定只是一个带有模板的 VS 错误。

    struct Foo {
        static void foo() {}
        void bar() {
            auto f = []() { foo(); };
            f();
        }
    };
    

    【讨论】:

    • 你试过什么编译器?结果似乎因编译器而异,因此了解符合标准的行为很重要。
    • @Gene : VC++ 2010 在N2927 之前实现了 lambdas,因此它符合 FDIS 的措辞。
    猜你喜欢
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 2021-05-29
    • 1970-01-01
    • 2011-10-03
    • 2023-03-12
    相关资源
    最近更新 更多