initializer_list和依赖于参数的查找

时间:2015-05-11 23:04:47

标签: c++ c++11 initializer-list argument-dependent-lookup

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

    #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。

2 个答案:

答案 0 :(得分:8)

我认为问题是子表达式 1 { a, a }实际上没有类型,因此它没有关联的类型或命名空间,这反过来意味着ADL会如果在全局命名空间中有一个函数,正常查找将找到它,并且它会发现{ a, a }可以将函数调用与std::initializer_list<Foo>的初始化函数匹配。

1 语法{ a, a }被称为 braced-init-list ,它实际上并不是语言中的表达式(或子表达式)。

答案 1 :(得分:2)

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