2012-12-15 39 views
12

Tôi có một lớp C, có một thành viên dữ liệu cá nhân string* ps.
Bây giờ, tôi muốn có một số unordered_map<C, int> mà tôi cần hàm băm tùy chỉnh.Hàm băm cho lớp do người dùng xác định. Làm thế nào để kết bạn? :)

According to the c++ reference, tôi có thể làm điều đó như

namespace std { 
    template<> 
    class hash<C> { 
    public: 
    size_t operator()(const C &c) const 
    { 
     return std::hash<std::string>()(*c.ps); 
    } 
    }; 
} 

Vấn đề là tôi dường như không thể làm cho operator()C bạn bè để tôi có thể truy cập vào ps.

Tôi đã thử này:

class C; 
template<> 
class std::hash<C>; 
class C{ 
    //... 
    friend std::hash<C>::operator()(const C&) const; // error: Incomplete type 
}; 
// define hash<C> here. 

nhưng nó nói rằng không đầy đủ loại ... trong tên lồng nhau specifier ...

Tôi không thể quay lại các định nghĩa hoặc, bởi vì nếu lớp C được xác định sau, hash<C> không có cách nào để biết về ps.

Tôi đang làm gì sai ở đây? Làm cách nào để khắc phục tình trạng này mà không cần thực hiện công khai ps?

Trả lời

15

Hãy thử điều này:

class C; 
namespace std { 
    template<> 
    class hash<C> { 
    public: 
    size_t operator()(const C &c) const; // don't define yet 
    }; 
} 
class C{ 
    //... 
    friend std::hash<C>::operator()(const C&) const; 
}; 
namespace std { 
    template<> 
    size_t hash<C>::operator()(const C &c) const { 
    return std::hash<std::string>()(*c.ps); 
    } 
} 

Hoặc này:

class C; 
template<> 
class std::hash<C>; 
class C{ 
    friend class std::hash<C>; // friend the class, not the member function 
}; 

(Tôi đã không được biên dịch nên có thể có một lỗi cú pháp)

+0

vâng, đúng vậy, thx, tôi sẽ đánh dấu nó được chấp nhận sau giây lát. Trong thời gian đó, tôi cũng đã tìm ra cách tôi ngớ ngẩn! [xấu hổ] :) –

+2

cho msvc2012, bạn sẽ cần phải loại bỏ 'mẫu <>' trong việc triển khai size_t 'hash :: toán tử()', nếu không 'lỗi C2910 không thể chuyên biệt rõ ràng'. – Jichao

+0

+1 cho Jichao. Trên Gcc mà không xóa 'template <>', tôi nhận được 'error: template-id 'operator() <>' cho toán tử 'std :: size_t std :: hash ::() (const C &) const' không khớp bất kỳ tuyên bố mẫu nào' – Conchylicultor

-1

tôi muốn đề nghị để thêm phương pháp như sau

class C 
{ 
.... 
public: const string* get_ps() const { return ps; } 
.... 
}; 

và sử dụng nó trong chuyên môn băm của bạn.

Các vấn đề liên quan