Tiêu chuẩn nói như sau về chuyên các mẫu từ thư viện chuẩn (thông qua What can and can't I specialize in the std namespace?)Có hợp pháp để chuyên chức năng thư viện std cho shared_ptr thuộc loại người dùng được xác định không?
Một chương trình có thể thêm một mẫu chuyên môn hóa cho bất kỳ thư viện mẫu tiêu chuẩn để namespace std chỉ nếu việc kê khai phụ thuộc vào một user- loại được xác định và chuyên môn đáp ứng các yêu cầu của thư viện chuẩn đối với mẫu gốc và không bị cấm rõ ràng.
Có hợp pháp để chuyên các mẫu thư viện chuẩn với lớp thư viện chuẩn chuyên biệt với lớp do người dùng xác định không? Ví dụ, chuyên std::hash
cho std::shared_ptr<MyType>
?
Từ đọc đoạn trên và câu hỏi được liên kết, có vẻ như nó phải như vậy, vì tuyên bố chuyên môn phụ thuộc vào MyType
, tuy nhiên "Trừ khi bị cấm một cách rõ ràng" làm tôi hơi lo lắng.
Ví dụ dưới đây biên dịch và hoạt động như mong đợi (AppleClang 7.3), nhưng nó có hợp pháp không?
#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);
}
Có, điều này là hợp pháp, không có giới hạn về chuyên môn của 'std :: hash' ngoại trừ * DefaultConstructible, CopyAssignable, Swappable và Destructible * (và tất cả các yêu cầu khác không liên quan gì đến * . Một ví dụ về * "rõ ràng bị cấm" * chuyên môn chuyên 'std :: numeric_limits' cho các loại tiêu chuẩn không phải số học. – Holt
Bạn cần có một cái nhìn về tra cứu Depument Dependend, bạn không cần thêm các hàm vào không gian tên std. –