将shared_ptr与自定义相等运算符和STL一起使用时出现问题

发布于 2024-10-24 08:21:15 字数 1655 浏览 1 评论 0原文

将共享指针与自定义相等运算符和 std::list 一起使用时似乎存在问题。

我整理了以下示例代码来演示该问题。

在尝试编译之前:

我使用 gcc version 4.5.2 20110127

和以下命令行:

g++ -g -O0 -std=gnu++0x test.cpp

如果未启用 c++0x 功能,则源代码将无法编译。

#include<list>
#include<boost/shared_ptr.hpp>

using std::list;
using std::shared_ptr;
using std::cout;
using std::endl;

class TestInt
{
   public:
      TestInt(int x);
      bool operator==(const TestInt& other);

   private:
      int _i;
};

TestInt::TestInt(int x)
{
   _i = x;
}

bool
TestInt::operator==(const TestInt& other)
{
   if (_i == other._i){
      return true;
   }
   return false;
}

class Foo
{
   public:
      Foo(TestInt i);
      shared_ptr<TestInt> f(TestInt i);

   private:
      list<shared_ptr<TestInt>> _x;
};

Foo::Foo(TestInt i)
{
   _x.push_back(shared_ptr<TestInt>(new TestInt(i)));
};

shared_ptr<TestInt>
Foo::f(TestInt i)
{
   shared_ptr<TestInt> test(new TestInt(i));
   int num = _x.size();
   list<shared_ptr<TestInt>>::iterator it = _x.begin();
   for (int j=0; j<num; ++j){
      if (test == *it){
         return test;
      }
      ++it;
   }
   throw "Error";
}

int main(){
   TestInt ti(5);
   TestInt ti2(5);
   Foo foo(ti);
   foo.f(ti2);
   std::cout << "Success" << std::endl;
}

我本以为代码会以 Success 结束,但它却抛出了异常。

test 前面插入 * 以及 *it 可以解决问题,但我的理解是,当共享指针调用 __a.get 时() == __b.get() 在其 == 运算符中应使用 TestInt 的自定义相等运算符。我不明白为什么不是。这是一个错误吗?

提前致谢。

There seems to be an issue when using shared pointers together with a custom equality operator and an std::list.

I put together the following example code to demonstrate the issue.

Before trying to compile this:

I'm using gcc version 4.5.2 20110127

with the following commandline:

g++ -g -O0 -std=gnu++0x test.cpp

The source won't compile if c++0x features aren't enabled.

#include<list>
#include<boost/shared_ptr.hpp>

using std::list;
using std::shared_ptr;
using std::cout;
using std::endl;

class TestInt
{
   public:
      TestInt(int x);
      bool operator==(const TestInt& other);

   private:
      int _i;
};

TestInt::TestInt(int x)
{
   _i = x;
}

bool
TestInt::operator==(const TestInt& other)
{
   if (_i == other._i){
      return true;
   }
   return false;
}

class Foo
{
   public:
      Foo(TestInt i);
      shared_ptr<TestInt> f(TestInt i);

   private:
      list<shared_ptr<TestInt>> _x;
};

Foo::Foo(TestInt i)
{
   _x.push_back(shared_ptr<TestInt>(new TestInt(i)));
};

shared_ptr<TestInt>
Foo::f(TestInt i)
{
   shared_ptr<TestInt> test(new TestInt(i));
   int num = _x.size();
   list<shared_ptr<TestInt>>::iterator it = _x.begin();
   for (int j=0; j<num; ++j){
      if (test == *it){
         return test;
      }
      ++it;
   }
   throw "Error";
}

int main(){
   TestInt ti(5);
   TestInt ti2(5);
   Foo foo(ti);
   foo.f(ti2);
   std::cout << "Success" << std::endl;
}

I would have expected that the code finishes with Success but instead it throws.

Inserting a * infront of test as well as *it fixes the issue but my understanding is that when the shared_ptr calles __a.get() == __b.get() in its == operator it should use the custom equality operator of TestInt. I don't understand why it is not. Is this a bug?

Thanks in advance.

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

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

发布评论

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

评论(2

魄砕の薆 2024-10-31 08:21:15

这是因为当您比较两个 shared_ptr 时,您比较的是引用,即两个实例指向的内存地址,而不是< /em> 基础值。

This is because when you compare two shared_ptr<T>, you are comparing the reference, that is, the memory address that the two instances point to, not the underlying values.

满意归宿 2024-10-31 08:21:15

您不是在比较 TestInt 对象,而是比较两个不同的指针,每个指针都指向自己的 TestInt 对象。所以本质上你的自定义等于运算符甚至没有被调用。

您所做的基本上是:

#include <iostream>

int main(int argc, char** argv) {
    int* pi1 = new int(5);
    int* pi2 = new int(5);
    if (pi1 == pi2)
        std::cout << "SUCCESS";
    else 
        std::cout << "ERROR";
}

现在应该很明显 pi1 和 pi2 不相等,并且代码完成打印 ERROR。

(事实上​​,我使用原始指针而不是共享指针并没有改变任何东西,但使逻辑更容易理解。与直接使用 int 而不是使用包装类相同。)

You're not comparing TestInt objects but rather two different pointers each pointing to its own TestInt object. So essentially your custom equals operator is not even called.

What you're doing is basically:

#include <iostream>

int main(int argc, char** argv) {
    int* pi1 = new int(5);
    int* pi2 = new int(5);
    if (pi1 == pi2)
        std::cout << "SUCCESS";
    else 
        std::cout << "ERROR";
}

Now it should be obvious that pi1 and pi2 are not equal and the code finishes printing ERROR.

(The fact that I have used a raw pointer instead of a shared_ptr doesn't change anything, but makes the logic easier to understand. Same with using int directly instead of using a wrapper class for it.)

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