标准说,有关标准库的专业模板(通过What can and can't I specialize in the std namespace?)为用户定义类型的shared_ptr专门化std库函数是否合法?
程序可以添加一个模板 专业化为任何标准库模板std名字空间仅 如果声明取决于用户以下并且 专业化符合 原始模板的标准库要求,并且未明确禁止。
将标准库模板与专门用户定义类的标准库类专门化是合法的吗?
例如,专门为std::shared_ptr<MyType>
专门设计std::hash
?
从阅读上面的段落和链接的问题,听起来应该是这样,因为专业化的声明依赖于MyType
,但是“除非明确禁止”稍微担心我。
下面的例子编译和按预期工作(AppleClang 7.3),但它是合法的吗?
#include <unordered_set>
#include <memory>
#include <cassert>
#include <string>
struct MyType {
MyType(std::string id) : id(id) {}
std::string id;
};
namespace std {
template<>
struct hash<shared_ptr<MyType>> {
size_t operator()(shared_ptr<MyType> const& mine) const {
return hash<string>()(mine->id);
}
};
template<>
struct equal_to<shared_ptr<MyType>> {
bool operator()(shared_ptr<MyType> const& lhs, shared_ptr<MyType> const& rhs) const {
return lhs->id == rhs->id;
}
};
}
int main() {
std::unordered_set<std::shared_ptr<MyType>> mySet;
auto resultA = mySet.emplace(std::make_shared<MyType>("A"));
auto resultB = mySet.emplace(std::make_shared<MyType>("B"));
auto resultA2 = mySet.emplace(std::make_shared<MyType>("A"));
assert(resultA.second);
assert(resultB.second);
assert(!resultA2.second);
}
是的,这是合法的,除了* DefaultConstructible,CopyAssignable,Swappable和Destructible *(以及与*无关的所有其他要求*“明确禁止”*),'std :: hash'没有特殊限制。 。 *“明确禁止”*特化的一个例子是专门为非算术标准类型的'std :: numeric_limits'。 – Holt
你应该看看参数Dependend查找,你不需要添加函数到std命名空间。 –