1

カスタム等値演算子および 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たが、代わりにスローされます。

*のinfront を挿入すると問題が修正testされます*itが、私の理解では、 shared_ptr__a.get() == __b.get()がその==演算子で呼び出すときは、 のカスタム等値演算子を使用する必要がありTestIntます。そうでない理由がわかりません。これはバグですか?

前もって感謝します。

4

2 に答える 2

10

これは、2つを比較するときに、参照、つまり、基になる値ではなくshared_ptr<T>、2つのインスタンスが指すメモリアドレスを比較しているためです。

于 2011-03-19T17:19:08.933 に答える
3

TestInt オブジェクトを比較するのではなく、それぞれ独自の TestInt オブジェクトを指す 2 つの異なるポインターを比較しています。したがって、基本的にカスタム equals 演算子は呼び出されません。

あなたがやっていることは基本的に次のとおりです。

#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 の出力を終了することは明らかです。

(shared_ptr の代わりに生のポインターを使用したという事実は、何も変更しませんが、ロジックを理解しやすくします。ラッパー クラスを使用する代わりに int を直接使用する場合と同じです。)

于 2011-03-19T20:27:39.277 に答える