基于参数的依赖名称查找

时间:2019-08-26 18:33:45

标签: c++ language-lawyer linkage argument-dependent-lookup dependent-name

This description on cppreference.com

  

模板中使用的从属名称的查找被推迟到知道模板参数为止,此时ADL会检查具有外部链接的函数声明,这些声明可以从任一模板定义上下文模板实例化上下文

与此相反,下面的代码片段compiles fine和三个编译器(MSVC,clang和gcc):

template <class T>
void CallFoo ()
{
    Foo (T ());
}


class Apple {};


int main ()
{
    CallFoo<Apple> ();
}


static void Foo (Apple)
{
}

FooCallFoo中的从属名称:它取决于模板参数T。但是,尽管违反了上面引用的两个规则,编译器仍然可以找到函数Foo

  • {{1}的声明在Foo的定义或实例中均不可见,因为它在两者之下。
  • CallFoo具有内部链接。

这三个编译器都不可能有错误。我可能误会了一些东西。您能详细说明一下吗?

1 个答案:

答案 0 :(得分:2)

在C ++ 03中,匿名命名空间的成员可以具有外部链接,尽管在其他翻译单元中无法命名。因此,认为可以将实际的static函数从从属ADL中排除。在C ++ 11中,匿名名称空间强加了内部链接,因此限制变得不合理。但是,尽管实现采用了新的行为,并且在2011年立即提出了一个问题(如评论中所述),但措词仍然保留在两个地方,直到2019年3月N4810

关于函数的放置,这是具有multiple points of instantiation的函数的构件,包括实例化它们的任何翻译单元的末尾(对C ++ 20中的模块进行了少许调整);如果实例化功能模板对于不同的选择产生不同的结果,则程序格式错误,无需诊断(如注释中所述)。