2012-12-15 10 views
12

Mam klasę C, która ma prywatny element danych string* ps.
Teraz chciałbym mieć unordered_map<C, int>, dla której potrzebuję niestandardowej funkcji skrótu.Funkcja skrótu dla klasy zdefiniowanej przez użytkownika. Jak się zaprzyjaźnić? :)

According to the c++ reference, mogę to zrobić jak

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

Problem polega na tym, że nie może wydawać się, aby operator() i C znajomych, abym mógł przejść ps.

Próbowałem to:

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

ale mówi, że Niekompletne typ ... w imię zagnieżdżonego specyfikatorem ...

nie mogę zawrócić definicji albo, bo jeśli klasy C jest zdefiniowany później, hash<C> nie ma sposobu, aby dowiedzieć się o ps.

Co ja tu robię źle? W jaki sposób można naprawić tę sytuację, nie publikując publicznie numeru ps?

Odpowiedz

15

Spróbuj tego:

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); 
    } 
} 

albo to:

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

(ja nie zebraliśmy więc nie może być błąd składni)

+0

tak, to prawda, thx, zaznaczę to akceptowane w sekundę. W międzyczasie zorientowałem się, jak głupio jestem! [zawstydzony] :) –

+2

dla msvc2012, musisz usunąć 'szablon <>' w implementacji size_t 'hash :: operator()', w przeciwnym razie 'błąd C2910 nie może być jawnie wyspecjalizowany'. – Jichao

+0

+1 dla Jichao. Na Gcc bez usuwania 'template <>', otrzymuję 'error: template-id 'operator() <>' dla 'std :: size_t std :: hash :: operator() (const C &) const' nie pasuje dowolna deklaracja szablonu " – Conchylicultor

-1

Sugeruję, aby dodać metodę jak po

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

i użyj go w swojej specjalizacji hash.

Powiązane problemy