boost::ptr_vector 和 find_if

发布于 2024-09-06 19:41:08 字数 1426 浏览 2 评论 0原文

我有一个课程:

//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::Try
” *' c:\program files\microsoft Visual Studio 9.0\vc\include\function 296

谁能告诉我我做错了什么以及如何纠正它。

I have a class:

//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));

    }
}

When I compile this, I get error:

Error 1 error C2440: 'initializing' :
cannot convert from 'const CMDatabase::Try' to 'CMDatabase::Try
*' c:\program files\microsoft visual studio 9.0\vc\include\functional 296

Can anyone pelase tell me what is it that I am doing wrong and how to correct it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

此岸叶落 2024-09-13 19:41:08

问题是您的 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 :复制 shared_ptr 确实有成本,因为它需要增加一个共享计数器,然后再减少它。

编辑

对粗心的人的提醒:指针容器库的设计使接口尽可能易于使用,好处之一是您不必双重取消引用。编译:

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

 int& i = *vec.begin();

因此,你的函子必须采用引用,而不是指针:)

The issue is that your equal method is not const qualified.

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

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

Note:

  • the const added to the method, otherwise it cannot be used on const objects
  • the const added on the pointer: copying shared_ptr does cost, because it necessitates incremented a shared counter, and decrementing it afterward.

EDIT:

Reminder for the unwary: the Pointer Container library has been designed so that the interface would be as easy to use a possible, and one of the goody is that you don't have to double dereference. This compiles:

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

 int& i = *vec.begin();

Thus, your functor must take a reference, not a pointer :)

﹎☆浅夏丿初晴 2024-09-13 19:41:08

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

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

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

其中以下内容仍然正确;)

或者您可以使用 operator[] 实现 < code>boost::ptr_vector 它将返回对该元素的引用:

for (std::size_t i = 0, l = ; defaultTry.size(); ++i) {
  CMDatabase::TryVectorIterator it = std::find_if(
    updateTry.begin(),
    updateTry.end(),
    std::bind1st(std::mem_fun(&CMDatabase::Try::equal), defaultTry[i])
  );
}

希望这会有所帮助。

Just for sake of completeness, the following statement is wrong! Thanks to Matthieu M. to point out my mistake!

On dereferencing an iterator of the boost pointer container you will get the pure pointer to the element. So you can try to dereference the pure pointer you get through the iterator:

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

Where the following is still correct ;)

Or you can use the the operator[] implementation of the boost::ptr_vector which will return a reference to the element:

for (std::size_t i = 0, l = ; defaultTry.size(); ++i) {
  CMDatabase::TryVectorIterator it = std::find_if(
    updateTry.begin(),
    updateTry.end(),
    std::bind1st(std::mem_fun(&CMDatabase::Try::equal), defaultTry[i])
  );
}

Hope this helps.

﹂绝世的画 2024-09-13 19:41:08

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

我尝试了两种方法。
第一个给出非法间接。

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

c:\program files\microsoft Visual Studio 9.0\vc\include\function(296) : error C2440: 'initializing' :无法从 'const CMDatabase::Try' 转换为 'CMDatabase ::尝试 *'
没有可用的用户定义转换运算符可以执行此转换,或者无法调用该运算符
c:\fta_chk\tools\channel_editor\ivodb\channellistupdate.cpp(103) :请参阅对函数模板实例化 'std::binder1st<_Fn2> 的引用std::bind1st,CMDatabase::Try>(const _Fn2 &,const _Ty &)' 正在编译

[
_Fn2=std::mem_fun1_t,
_结果=布尔值,
_Ty=CMDatabase::尝试,
_Arg=CMDatabase::TryPtr
]

Sorry, For soem reason, i could not add comment to previous post, so I am writing it as answer.

I tried both the methods.
First one gives, illegal indirection.

And for the second one, it gives the same error:
In verbose output, the details are as follows:

c:\program files\microsoft visual studio 9.0\vc\include\functional(296) : error C2440: 'initializing' : cannot convert from 'const CMDatabase::Try' to 'CMDatabase::Try *'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
c:\fta_chk\tools\channel_editor\ivodb\channellistupdate.cpp(103) : see reference to function template instantiation 'std::binder1st<_Fn2> std::bind1st,CMDatabase::Try>(const _Fn2 &,const _Ty &)' being compiled
with
[
_Fn2=std::mem_fun1_t,
_Result=bool,
_Ty=CMDatabase::Try,
_Arg=CMDatabase::TryPtr
]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文