【问题标题】:ADL fails when invoking function within a lambda在 lambda 中调用函数时 ADL 失败
【发布时间】:2017-12-03 16:41:59
【问题描述】:

我正在尝试从 lambda 调用一个函数,该函数是在特定成员函数中运行 std::for_each 的一部分。 这里的例子: https://godbolt.org/g/KCBLjL

namespace A {
  struct Foo {
    int a;
    int b;
  };

  void dump(const A::Foo& v) {
      std::cout << v.a << v.b << std::endl;
  }
} // ns A

class B {
public:
   void dump() const {
       (void)std::for_each(std::begin(foo), std::end(foo),
                           [](const A::Foo &f){
                           dump(f); // <- fails here, I expected ADL to kick in
       });
   }
private:
   std::vector<A::Foo> foo = { A::Foo{}, A::Foo{} };
};

得到:

<source>: In lambda function:
21 : <source>:21:19: error: no matching function for call to 
'B::dump(const A::Foo&)'
         dump(f);
               ^
18 : <source>:18:10: note: candidate: void B::dump() const
         void dump() const {

为什么 ADL 在这里失败了? 我假设编译器会找到 B::dump 但也因为 A::Foo 在同一个命名空间中有 dump(const Foo&) ,编译器会将其添加为选项。但它不起作用。用-std=c++17编译

【问题讨论】:

    标签: c++


    【解决方案1】:

    [basic.lookup.argdep]/3,强调我的:

    X为非限定查找产生的查找集,令Y为参数依赖查找产生的查找集(定义如下)。 如果 X 包含

    • 类成员的声明,或
    • 不是 using 声明的块范围函数声明,或
    • 既不是函数也不是函数模板的声明

    那么 Y 为空。

    【讨论】:

      【解决方案2】:
      void dump() const {
      

      问题是您已经有一个名为 dump() 的符号,在此方法中包含 lambda 调用的范围内,here。这优先。

      如果将此方法命名为dump2(),则查找会按预期成功。

      The key rule here:

      ... 在其参数的命名空间中查找 除了 通常的非限定名称所考虑的范围和命名空间 查找

      强调我的。 “除了通常的非限定名称查找所考虑的范围和命名空间之外的范围和命名空间”。

      “通常的”非限定名称查找在调用类中找到 dump() 符号。句号。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-02-08
        • 2023-01-02
        • 2019-04-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-28
        相关资源
        最近更新 更多