繁体   English   中英

我应该专门化或重载在 `std::swap` 之类的命名空间中定义的模板吗?

[英]Should I specialize or overload templates defined in a namespace like `std::swap`?

如果我有一些 class 类型来管理例如资源,并且我的 class 需要定义一个swap() function 作为其接口的一部分,它适用于以下对象:

struct Foo{};

Foo f1, f2;

void swap(Foo& lhs, Foo& rhs){
    // code to swap member data of lhs and rhs
}

int main(){
    using std::swap;
    Foo f1, f2;
    swap(f1, f2);
}
  • 现在,我是重载std::swap还是专门化它?

  • 我了解到,如果我想专门化标准库的函数/类模板,那么我应该打开命名空间std并在那里声明专门化。 例如:

namespace std{
    void swap(Foo&, Foo&);
}
  • 我记得当我将std::hash专门用于我打算用作无序关联容器的元素类型的类型时,例如std::unordered_map ,我确实专门std::hash这样:
namespace std{ // opening namespace std
    template<>
    class hash<Foo>{
          //...
    };
}

那么,这是正确的吗? 我应该重载还是专门std::swap

该标准通常不允许在命名空间std中添加重载或特化:

[namespace.std]/1除非另有说明,否则如果 C++ 程序将声明或定义添加到命名空间std或命名空间std内的命名空间,则它的行为是未定义的。

特化 class 模板有一个例外。 您的std::hash<Foo>示例属于:

[namespace.std]/2除非明确禁止,否则程序可以将任何标准库 class 模板的模板特化添加到命名空间std ,前提是 (a) 添加的声明依赖于至少一个程序定义的类型和 (b) 特化满足原始模板的标准库要求。

您可以在命名空间std之外重载某些标准库函数,依靠 ADL 来找到它们:

[namespace.std]/7除了命名空间std或命名空间std内的命名空间之外,程序可以为任何指定为自定义点的库 function 模板提供重载,前提是 (a) 重载的声明至少取决于用户定义类型和 (b) 重载满足定制点的标准库要求。 [注意:这允许对自定义点进行(合格或不合格)调用,以调用给定 arguments 的最合适的重载。 ——尾注]

std::swap实际上是一个定制点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM