我在boost :: intrusive_ptr中包含一个Locker类型的小模板类,我希望将其存储在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只是一个容器类;它的构造函数如下:
template <typename T>
Locker<T>::
Locker(T* pData)
: IntrusivePtrCountable(),
mpData(pData),
mThreadId(0),
mDataRefCount(0)
{}
在我对这堂课的考试中,我试图做到以下几点:
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;
};
我收到以下编译错误:
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
请帮忙
答案 0 :(得分:2)
实际上,intrusive_ptr已经有了&lt;运算符和复制构造函数已定义,因此不是问题。
我们缺少两件主要的事情。首先,我们需要使用value_type
而不是make_pair
来避免insert
语句中的隐式类型转换。其次,我们错过了intrusive_ptr构造函数将指针带到模板化的类型的事实。
所以,最终的工作方法如下所示:
// ---------------------------------------------------------------------------
// 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 :(得分:1)
编译器正在尽力在这里提供帮助。您需要使用以下签名定义方法:
boost::intrusive_ptr<Locker<Clayton> >::intrusive_ptr(
boost::intrusive_ptr<Locker<Clayton> > (* const&)(Locker<Clayton>)
):
您需要为存储在std :: map中的类型定义复制构造函数,这是此错误消息尝试传达的内容。你还应该实现&lt;运算符,以便满足以下条件:
- ( 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 )
对于许多内置类型,C ++将为您提供这些,这就是为什么有些人不知道您需要做什么来在std :: map和其他STL容器中存储自定义对象。