c++ - 在匿名命名空间中定义模板特化(和编译错误 C2888)

标签 c++ templates namespaces template-specialization

果壳版:为什么我不能在编译单元/cpp 文件内的匿名命名空间中定义仅在当前编译单元中有用的模板特化(std-lib 类型)?

加长版:

我有一个类型,它只是一个 cpp 文件中的快速助手,我们称之为 struct Helper .因为它只在那个编译单元中使用,所以它是在 cpp 内的匿名命名空间中声明和定义的。

因为我想要一个 std::unordered_set<Helper> ,我要专攻std::hash .当我现在尝试在同一个匿名命名空间中定义它时,我得到一个 C2888 'std::hash<'anonymous-namespace'::Helper>': symbol cannot be defined within namespace 'anonymous-namespace' .这是为什么?

我尝试添加 using namespace std AN里面也有类似的东西,但是没有用。

/* This doesn't work */

namespace
{
    struct Helper
    {
        int member1;
        bool member2;
    };

    using namespace std;
    template<>
    struct std::hash<Helper>
    {
        size_t operator()(const Helper& helper) const
        {
            return 12345; /* how it's really generated is irrelevant here */
        }
    };
}

当然,我可以将特化放在 AN 之外,并且它有效。我只是想了解为什么它在里面时没有!
/* This works, but why doesn't the other? */

namespace
{
    struct Helper
    {
        int member1;
        bool member2;
    };
}

template<>
struct std::hash<Helper>
{
    size_t operator()(const Helper& helper) const
    {
        return 12345; /* how it's really generated is irrelevant here */
    }
};

最佳答案

属于命名空间的符号 std必须在包含 std 的命名空间中定义这意味着您必须在全局命名空间中定义它。

这是来自 C2888 的示例:

namespace M {
   namespace N {
      void f1();
      void f2();
   }

   void N::f1() {}   // OK: namspace M encloses N
}

namespace O {
   void M::N::f2() {}   // C2888 namespace O does not enclose M
}

[temp.expl.spec/9] 来自 C++20 草案:

A template explicit specialization is in the scope of the namespace in which the template was defined. [ Example:

namespace N {
  template<class T> class X { /* ... */ };
  template<class T> class Y { /* ... */ };

  template<>
  class X<int> { /* ... */ };     // OK: specialization in same namespace

  template<>
  class Y<double>;                // forward-declare intent to specialize for double
}

template<>
class N::Y<double> { /* ... */ }; // OK: specialization in enclosing namespace

template<>
class N::Y<short> { /* ... */ };  // OK: specialization in enclosing namespace

— end example ]

关于c++ - 在匿名命名空间中定义模板特化(和编译错误 C2888),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60735913/

相关文章:

python - Sphinx 自动图像编号/标题?

php - 如何修复新文件夹项目中未确定的命名空间?

c++ - this 指针和 QSharedPointer

python - Numpy C API - 使用 PyArray_Descr 进行数组创建会导致段错误

c++ - 我应该为需要在堆上分配的多态类制作包装器吗?

java - 枚举外部驱动器

c++ - Effective C++ Item 43 了解如何访问模板化基类中的名称

c++ - 用于实例化模板化代码的显式习惯用法 - 不包含其源代码

.net - 删除根节点下的所有命名空间

c++ - 嵌套迭代器类不命名类型