Help save intrusive_ptr of the template class to std :: map

I have a small class of Locker type templates contained in boost :: intrusive_ptr that I want to save inside std :: map:

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 is just a container class; its constructor looks like this:

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

In my testing of this class, I am trying to do the following:

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

I get the following compilation error:

 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 

Please, help

+4
source share
2 answers

In fact, intrusive_ptr already has a <operator and copy constructor, so this is not a problem.

There were two main things that we lacked. First, we needed to use value_type instead of make_pair to avoid implicit type conversion in the insert . Secondly, we missed the fact that the intrusive_ptr constructor accepts a pointer to the type that he disguised around.

So, the final, working method is as follows:

 // --------------------------------------------------------------------------- // 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 
+2
source

The compiler does everything possible to be useful here. You need to define a method with the following signature:

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

You need to define a copy constructor for the types that you store on std :: map, which is trying to pass this error message. You must also implement the <operator so that the following is true:

 - ( 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 ) 

For many built-in C ++ types, they will be provided for you, so some people do not know what you need to do to store custom objects in std :: map and other STL containers.

+1
source

All Articles