initializer_list 和参数相关的查找

initializer_list and argument-dependent lookup

我正在尝试将 std::initializer_list 用作使用参数相关查找 (ADL) 的函数中的参数。但我没有让它工作,我不明白为什么。以下是一个最小的失败示例:

    #include <initializer_list>
    #include <iostream>

    class Foo {
    public:
      inline friend void bar(std::initializer_list<Foo> v) {
        std::cout << "size = " << v.size() << std::endl;
      }
    };

    void baz(std::initializer_list<Foo> v) {
      std::cout << "size = " << v.size() << std::endl;
    }

    int main(){
      Foo a;
      //bar({a,a});   // error: use of undeclared identifier 'bar'
      baz({a,a});   // works

      return 0;
    }

如上所示,等效的全局函数工作得很好。为什么以上不起作用?

我在 OS X 10.10 上使用 clang。

当编译器看到 bar({a,a}) 时,它不知道参数的类型,因此它会在全局命名空间 (::) 中搜索 bar,而不会在其他任何地方搜索.如果您将该行更改为 Foo{a,a},那么它知道参数是 Foo,因此还会在 Foo class 中搜索函数。

我认为问题在于子表达式1 { a, a } 并没有真正的类型,因此它没有关联的类型或名称空间turn 意味着 ADL 不启动。如果你在全局命名空间中有一个函数,正常查找会找到它,它会发现 { a, a } 可以匹配函数调用作为 std::initializer_list<Foo> 的初始化程序。

1 语法 { a, a } 被称为 braced-init-list 它并不是一个真正的表达式(或子表达式) 在语言中。