2009-04-11 4 views
4

J'ai une petite classe de modèle de type Locker contenu dans un coup de pouce :: intrusive_ptr que je veux stocker dans un std :: carte:stocker une aide intrusive_ptr d'une classe de modèle dans un std :: carte

template <typename T> 
bool LockerManager<T>:: 
    AddData(const std::string& id, T* pData) 
{ 

    boost::intrusive_ptr<Locker<T> > lPtr(Locker<T>(pData)); // Line 359 - compiles 

    mMap.insert(make_pair(id, lPtr)); // Line 361 - gives error 
} 

Locker est juste une classe de conteneur; son constructeur ressemble:

template <typename T> 
Locker<T>:: 
    Locker(T* pData) 
    : IntrusivePtrCountable(), 
    mpData(pData), 
    mThreadId(0), 
    mDataRefCount(0) 
{} 

Dans mon test de cette classe, je suis en train de faire ce qui suit:

class Clayton 
{ 
public: 
    static int count; 

    Clayton() 
    { mNumber = count++;} 

    void GetNumber() 
    { cerr<<"My number is: "<<mNumber<<endl; } 

private: 
    int mNumber; 
}; 

int Clayton::count = 0; 

class ClaytonManager 
{ 
public: 
    bool AddData(const std::string& id, Clayton* pData) 
    { return mManager.AddData(id, pData); } 

private: 
    LockerManager<Clayton> mManager; 
}; 

j'obtiens l'erreur de compilation suivante:

Compiling LockerManagerTest.cpp        : /usr/local/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../../include/c++/3.4.6/bits/stl_pair.h: In constructor `std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U1 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _U2 = boost::intrusive_ptr<Locker<Clayton> > (*)(Locker<Clayton>), _T1 = const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _T2 = boost::intrusive_ptr<Locker<Clayton> >]': 
../Utilities/include/LockerManager.h:361: instantiated from `bool LockerManager<T>::AddData(const std::string&, T*) [with T = Clayton]' 
src/LockerManagerTest.cpp:35: instantiated from here 
/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../../include/c++/3.4.6/bits/stl_pair.h:90: error: no matching function for call to `boost::intrusive_ptr<Locker<Clayton> >::intrusive_ptr(boost::intrusive_ptr<Locker<Clayton> > (* const&)(Locker<Clayton>))' 
/usr/local/boost-1.36.0/include/boost-1_36/boost/intrusive_ptr.hpp:94: note: candidates are: boost::intrusive_ptr<T>::intrusive_ptr(const boost::intrusive_ptr<T>&) [with T = Locker<Clayton>] 
/usr/local/boost-1.36.0/include/boost-1_36/boost/intrusive_ptr.hpp:70: note:     boost::intrusive_ptr<T>::intrusive_ptr(T*, bool) [with T = Locker<Clayton>] 
/usr/local/boost-1.36.0/include/boost-1_36/boost/intrusive_ptr.hpp:66: note:     boost::intrusive_ptr<T>::intrusive_ptr() [with T = Locker<Clayton>] 
Command exited with non-zero status 1 
0:05.40 

S'il vous plaît aider

Répondre

2

En fait, intrusive_ptr a déjà un opérateur < et un constructeur de copie défini, ce qui n'était pas le problème.

Il y avait deux choses principales qui nous manquaient. Tout d'abord, nous devions utiliser value_type, au lieu de make_pair, pour éviter la conversion de type implicite dans l'instruction insert. Deuxièmement, nous avons manqué le fait que le constructeur intrusive_ptr prend un pointeur au type qu'il est autour du modèle.

Ainsi, la finale, la méthode de travail ressemble à ceci:

// --------------------------------------------------------------------------- 
// LockerManager::AddData 
// --------------------------------------------------------------------------- 
template <typename T> 
bool LockerManager<T>:: 
    AddData(const std::string& id, T* pData) 
{ 
    Lock<MutualExclusion> lLock(mMutex); 

    if ((pData == NULL) || (mMap.find(id) != mMap.end())) 
    return false; 

    mMap.insert(typename std::map<std::string, boost::intrusive_ptr<Locker<T> > >::value_type(id, new Locker<T>(pData))); 

    return true; 
} // LockerManager::AddData 
1

Le compilateur fait de son mieux pour être utile ici. Vous devez définir une méthode avec la signature suivante:

boost::intrusive_ptr<Locker<Clayton> >::intrusive_ptr(
    boost::intrusive_ptr<Locker<Clayton> > (* const&)(Locker<Clayton>) 
): 

Vous devez définir un constructeur de copie pour les types que vous stockez dans un std :: carte, c'est ce que ce message d'erreur essaie de transmettre. Vous devez également mettre en œuvre l'opérateur < de sorte que ce qui suit est vrai:

- (x < x) == false 
- if (x < y), then !(y < x) 
- if (x == y), then (x < y) == (y < x) == false 
- if (x < y) and (y < z), then (x < z) 

Pour un grand nombre de types intégrés en C++ fournira ces pour vous, ce qui explique pourquoi certaines personnes ne savent pas ce que vous avez à faire pour stocker des objets personnalisés dans std :: map et d'autres conteneurs STL.

+0

devrait-il pas boost :: intrusive_ptr ont déjà un constructeur de copie et Clayton

Questions connexes