7

cppreference.com 上的这个描述

模板中使用的依赖名称的查找被推迟到知道模板参数之前,此时 [...] ADL 检查具有外部链接的函数声明,这些链接可以从模板定义上下文模板实例化上下文中看到。

与此相反,以下代码片段可以使用三个编译器(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有内部联系。

三个编译器都不太可能有错误。我可能误会了什么。你能详细说明一下吗?

4

1 回答 1

3

在 C++03 中,匿名命名空间的成员可以具有外部链接,尽管在其他翻译单元中是不可命名的。因此,认为可以static从相关 ADL 中排除实际功能。在 C++11 中,匿名命名空间强加了内部链接,因此限制变得不合理。然而,尽管实施采用了新行为并且在 2011 年立即提交了一个问题(如评论中所述),但在 2019 年 3 月的N4810之前,该措辞仍然存在于两个地方。

至于函数的放置,这是具有多个实例化点的函数的产物,包括实例化它们的任何翻译单元的末尾(对 C++20 中的模块稍作调整);如果实例化函数模板为不同的选择产生不同的结果,则程序格式错误,不需要诊断(如注释中所述)。

于 2019-08-27T01:23:39.393 回答