boost :: ptr_vector和find_if

时间:2010-06-24 08:44:53

标签: c++ boost ptr-vector

我有一个班级:

//header file
class CMDatabase
{
    class Try;
    typedef boost::shared_ptr<Try> TryPtr;
    typedef boost::ptr_vector<Try> TryVector;
    typedef TryVector::iterator TryVectorIterator;

    class Try
    {
        public:
            virtual ~Try();
            virtual bool equal(CMDatabase::TryPtr mySd) = 0;
    };
};

//.cpp file

class TryImpl : public CMDatabase::Try
{
    bool equal(CMDatabase::TryPtr mySd)
    {
        //boost::shared_ptr<ServiceDataImpl> ServiceDataImplPtr;
        //const ServiceDataImplPtr pOtherData = dynamic_cast<const ServiceDataImplPtr>(mySd);

        //ServiceDataImpl *pOtherData = dynamic_cast<ServiceDataImpl *>(mySd.get());
        return true;
    }
};

//Another .cpp file

void UpdateClass::TryFind()
{
    CMDatabase::TryVector defaultTry;
    CMDatabase::TryVector updateTry;

//Code for filling two vectors here....

    for(CMDatabase::TryVectorIterator i = defaultTry.begin(); i != defaultTry.end(); ++i)
    {
       CMDatabase::TryVectorIterator it = find_if(updateTry.begin(), updateTry.end(),bind1st(mem_fun(&CMDatabase::Try::equal), *i));

    }
}

当我编译它时,我收到错误:

  

错误1错误C2440:'初始化':
  无法从'const CMDatabase :: Try'转换为'CMDatabase ::试试
  *'c:\ program files \ microsoft visual studio 9.0 \ vc \ include \ functional 296

任何人都可以告诉我,我做错了什么以及如何纠正它。

3 个答案:

答案 0 :(得分:1)

为了完整起见,以下陈述是错误的!感谢Matthieu M.指出我的错误!

在取消引用boost指针容器的迭代器时,您将获得指向该元素的纯指针。因此,您可以尝试取消引用通过迭代器获得的纯指针:

CMDatabase::TryVectorIterator it =
  find_if(updateTry.begin(), updateTry.end(), bind1st(mem_fun(&CMDatabase::Try::equal), **i));

以下内容仍然正确;)

或者您可以使用operator[]的{​​{1}}实现,它将返回对该元素的引用:

boost::ptr_vector

希望这有帮助。

答案 1 :(得分:1)

问题是您的equal方法不符合const

class Try
{
public:
  virtual ~Try();
  virtual bool equal(CMDatabase::TryPtr const& mySd) const = 0;
};

bool TryImpl::equal(CMDatabase::TryPtr const& mySd) const { return true; }

注意:

  • const添加到方法中,否则无法在const个对象上使用
  • 在指针上添加了const:复制shared_ptr确实有成本,因为它需要增加一个共享计数器,然后递减它。

修改

提醒粗心大意:指针容器库的设计使得界面尽可能易于使用,其中一个好处是你不必双重取消引用。这编译:

 boost::ptr_vector<int> vec;
 vec.push_back(new int(3));

 int& i = *vec.begin();

因此,您的仿函数必须采用引用,而不是指针:)

答案 2 :(得分:0)

抱歉,由于soem原因,我无法在上一篇文章中添加评论,所以我将其写为答案。

我尝试了两种方法。 第一个是非法间接的。

对于第二个,它给出了同样的错误: 在详细输出中,详细信息如下:

c:\ program files \ microsoft visual studio 9.0 \ vc \ include \ functional(296):错误C2440:'initializing':无法从'const CMDatabase :: Try'转换为'CMDatabase :: Try *'         没有可用于执行此转换的用户定义转换运算符,或者无法调用运算符         c:\ fta_chk \ tools \ channel_editor \ ivodb \ channellistupdate.cpp(103):参见函数模板实例化'std :: binder1st&lt; _Fn2&gt; std :: bind1st,CMDatabase :: Try&gt;(const _Fn2&amp;,const _Ty&amp;)'正在编译         同         [             _Fn2 =标准:: mem_fun1_t,             _result =布尔,             _Ty = CMDatabase ::试试,             _Arg = CMDatabase :: TryPtr         ]