我正在尝试在使用参数依赖查找(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。
答案 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
类中搜索函数。