不同命名空间中'template <class _Tp> struct std :: less'的专业化

Sti*_*MAN 30 c++

我专注于数据类型的'less'(谓词).

代码如下所示:

template<>
struct std::less<DateTimeKey>
{
   bool operator()(const DateTimeKey& k1, const DateTimeKey& k2) const
   {
      // Some code ...
   }
}
Run Code Online (Sandbox Code Playgroud)

编译时(在Ubuntu 9.10上使用g ++ 4.4.1),我得到错误:

不同命名空间中'template struct std :: less'的专业化

我做了一些研究,发现有一个'解决方法'涉及将特化包装在std命名空间中 - 即将代码更改为:

namespace std {
template<>
struct less<DateTimeKey>
{
   bool operator()(const DateTimeKey& k1, const DateTimeKey& k2) const
   {
      // Some code ...
   }
}
}
Run Code Online (Sandbox Code Playgroud)

确实,关闭了编译器.然而,这个解决方案来自一个5岁的职位(由'伟大的'Victor Bazarof而不是[双关语]).这个解决方案还有很长的路要走,还是有更好的方法来解决这个问题,还是"老方法"仍然有效?

Jon*_*onM 27

这仍然是做到这一点的方法.遗憾的是,您不能像在类中那样声明或定义命名空间中的函数:您需要将它们实际包装在命名空间块中.


Dav*_*eas 24

如果需要专门化标准算法,可以在std命名空间中执行此操作.根据标准,您唯一可以在该命名空间内执行此操作.

[lib.reserved.names]/1

除非另有说明,否则C++程序未定义向命名空间std中的命名空间std或命名空间添加声明或定义.程序可以将任何标准库模板的模板特化添加到命名空间std.标准库模板的这种特化(完整或部分)会导致未定义的行为,除非声明取决于用户定义的外部链接名称,除非专门化符合原始模板的标准库要求

现在,问题是你是否真的想要专攻std::less.请注意,std::less将调用为您的类型定义的比较运算符,因此您可以提供该操作而不是专门化模板.

专门std::less针对您的特定类型的问题是,如果您提供的操作与operator< 您的类型执行的操作不同,则会导致混淆.如果它们执行相同的操作,只需保留默认std::less定义而不进行专门化.

如果您不想提供比较运算符,但仍想使用关联容器中的类型或需要使用比较器的算法,则可以通过其他名称提供外部比较仿函数,这不会混淆其他读者(以及您自己的某个地方)未来).