2009-04-11 63 views
4

我有一个小模板类包含一个boost :: intrusive_ptr内式储物柜的,我想存储一个std ::地图里:帮助存储模板类的intrusive_ptr在一个std ::地图

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 
} 

储物柜只是一个容器类;它的构造是这样的:

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 

请帮助

回答

2

事实上,intrusive_ptr已经有一个<运算符和一个拷贝构造函数的定义,所以这不是问题。

我们错过了两件主要的事情。首先,我们需要使用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

编译器正在尽最大努力在此处提供帮助。您需要定义一个方法具有以下签名:

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

您需要定义一个拷贝构造函数为您在一个std ::地图存储类型,这就是此错误信息要传达。你也应该实现<运营商,使符合下列条件:

- (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容器中。

+0

不应该的boost :: intrusive_ptr已经有一个拷贝构造函数和<运营商定义的? – Clayton 2009-04-12 01:00:00