標準說,有關標準庫的專業模板(通過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命名空間。 –