This description on cppreference.com说
The lookup of a dependent name used in a template is postponed until the template arguments are known, at which time [...] ADL examines function declarations with external linkage that are visible from either the template definition context or the template instantiation context.
与此相反的是下面的代码片段compiles fine使用三个编译器(MSVC、clang、gcc):
template <class T>
void CallFoo ()
{
Foo (T ());
}
class Apple {};
int main ()
{
CallFoo<Apple> ();
}
static void Foo (Apple)
{
}
Foo
是 CallFoo
中的依赖名称:它依赖于模板参数 T
。但是函数 Foo
被编译器找到,尽管它违反了上面引用的两个规则。
Foo
的声明在CallFoo
的定义或实例化中都不可见,因为它在两者之下。Foo
有内部链接。
不太可能所有三个编译器都有错误。我可能误会了什么。你能详细说明一下吗?
最佳答案
在 C++03 中,匿名命名空间的成员可以有外部链接,尽管在其他翻译单元中是不可命名的。因此,从依赖 ADL 中排除实际的 static
函数被认为是允许的。在 C++11 中,匿名命名空间强加了内部链接,因此限制变得不合理。然而,尽管实现采用了新行为并在 2011 年立即提交了一个问题(如评论中所述),但措辞仍保留在两个地方,直到 N4810。 2019 年 3 月。
至于函数的放置,这是具有 multiple points of instantiation 的函数的产物,包括实例化它们的任何翻译单元的结尾(对 C++20 中的模块进行了轻微调整);如果实例化函数模板对不同的选择产生不同的结果,则程序格式错误,不需要诊断(如评论中所述)。
关于c++ - 相关名称的参数相关查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57663135/