c++ - 在内联匿名命名空间中声明的全局命名空间中定义模板函数时 undefined reference

标签 c++ c++17 language-lawyer

给定:

namespace ns
{
  inline namespace
  {
    template<typename T>
    void f();
  }
}

template<typename T>
void ns::f() {}

int main()
{
    ns::f<int>();
}

GCC(主干)提示 ns::f<int>没有定义。 Clang (trunk) 对此没问题。请参阅:https://godbolt.org/z/n5qMs85q5

这是 GCC 中的已知错误吗? Clang 不正确吗?

最佳答案

GCC 是对的,程序格式错误。

inline 命名空间的成员可以做什么在 [namespace.def]/7 中指定。 :

Members of an inline namespace can be used in most respects as though they were members of the enclosing namespace. Specifically, the inline namespace and its enclosing namespace are both added to the set of associated namespaces used in argument-dependent lookup whenever one of them is, and a using-directive that names the inline namespace is implicitly inserted into the enclosing namespace as for an unnamed namespace. Furthermore, each member of the inline namespace can subsequently be partially specialized, explicitly instantiated, or explicitly specialized as though it were a member of the enclosing namespace. Finally, looking up a name in the enclosing namespace via explicit qualification ([namespace.qual]) will include members of the inline namespace brought in by the using-directive even if there are declarations of that name in the enclosing namespace.

因此,内联 命名空间成员可以被查找,甚至可以专门化使用它的封闭范围名称,但不是定义

要定义一个成员,您仍然需要完全限定它。但是您不能限定未命名的命名空间。

要修复它,只需给它起个名字:

namespace ns
{
  inline namespace X
  {
    template<typename T>
    void f();
  }
}

template<typename T>
void ns::X::f()
{
  T t{};
  ++t;
}

奖金信息:

要了解未命名命名空间的工作原理,请参阅 [namespace.unnamed]/1 :

An unnamed-namespace-definition behaves as if it were replaced by

inline(opt) namespace unique { /* empty body */ }
using namespace unique ;
namespace unique { namespace-body }

所以一个未命名的命名空间实际上有一个名字,它只是对用户隐藏了。因此它永远不能完全限定其中的内容(这实际上是重点)。

[namespace.memdef]/2 :

Members of a named namespace can also be defined outside that namespace by explicit qualification ...

这基本上意味着如果你能限定它,你就可以定义它

关于c++ - 在内联匿名命名空间中声明的全局命名空间中定义模板函数时 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68283195/

相关文章:

c++ - 如果 constexpr 与 sfinae

c++ - 对 'distance'的错误引用是含糊的

c++ - 返回指向intent(in)参数的指针

c++ - 使用函数的 decltype 生成的非类型模板参数

c++ - 作为函数参数和返回值的不完整类型

c++ - 在 C++ 中编写移动构造函数时是否必须编写复制构造函数?

c++ - 文本文档中只有左边框

c++ - if 在 while 循环内造成麻烦

c++ - 我必须使用 boost::bind 来创建多态 "transform"功能吗?

c++ - 为什么 <> 在指定一个所有模板参数都有默认值的模板类时是必需的?