果壳版:为什么我不能在编译单元/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/