请考虑以下示例:
struct S {
template<typename T = void>
friend void foo(S) {
}
};
int main() {
S s;
foo(s); // (1)
foo<void>(s); // (2)
}
我的GCC 9.2.0无法编译(2)
,并出现以下错误:
a.cpp: In function 'int main()':
a.cpp:10:5: error: 'foo' was not declared in this scope
10 | foo<void>(s);
| ^~~
a.cpp:10:9: error: expected primary-expression before 'void'
10 | foo<void>(s);
| ^~~~
但是,(1)
工作正常。为什么是这样?如何使用显式模板参数调用foo
?
它是模板的事实无关紧要。只能在ADL查找中找到在声明它们的位置定义的Friend函数。当您使用模板参数时,编译器会尝试使用正常的非限定性查找来寻找名为foo
的功能模板,但它会失败。 foo(s)
使用关联的名称空间foo
(全局名称空间)查找s
,并找到您已定义的好友函数。