2

ポインターとしてベクターに格納している単純なクラスがあります。ベクトルで検索を使用したいのですが、オブジェクトが見つかりません。デバッグ時に、私が提供した == 演算子を呼び出していないようです。デバッガーでオブジェクトを「見る」ことができるので、そこにあることがわかります。以下のコードは、リストの最初の項目のコピーを使用していますが、それでも失敗します。これを通過させる唯一の方法は、MergeLine* mlt = LineList.begin() を使用することです。これは、オブジェクトを比較していて、等値演算子をまったく使用していないことを示しています。

class MergeLine {
public:
   std::string linename;
   int StartIndex;
   double StartValue;
   double FidStart;
   int Length; 

   bool operator <  (const MergeLine &ml) const {return FidStart < ml.FidStart;}
   bool operator == (const MergeLine &ml) const {
         return linename.compare( ml.linename) == 0;}    
};

Class OtherClass{
public:
   std::vector<MergeLine*>LineList;
   std::vector<MergeLine*>::iterator LL_iter;
   void DoSomething( std::string linename){
 // this is the original version that returned LineList.end()
 //   MergeLine * mlt
 //   mlt->linename = linename;

 // this version doesn't work either (I thought it would for sure!)
      MergeLine *mlt =new MergeLine(*LineList.front());
      LL_iter = std::find(LineList.begin(), LineList.end(), mlt);
      if (LL_iter == LineList.end()) {
         throw(Exception("line not found in LineList : " + mlt->linename));
      }
      MergeLine * ml = *LL_iter;

    }
};

乾杯、マーク

4

3 に答える 3

2

コンテナーにはオブジェクトではなくポインターが含まれているため、比較はポインター間で行われます。ポインターが等しくなる唯一の方法は、それらがまったく同じオブジェクトを指している場合です。お気づきのように、オブジェクト自体の比較演算子は決して呼び出されません。

std::find_if使用する比較オブジェクトを使用して渡すことができます。

class MergeLineCompare
{
    MergeLine * m_p;
public:
    MergeLineCompare(MergeLine * p) : m_p(p)
    {
    }
    bool operator()(MergeLine * p)
    {
        return *p == *m_p;
    }
};

LL_iter = std::find_if(LineList.begin(), LineList.end(), MergeLineCompare(mlt));
于 2013-07-31T22:24:19.557 に答える
1

あなたが本当に欲しいのは、std::find_if 次のように使うことだと思います:

struct MergeLineNameCompare
{
    std::string seachname;

    MergeLineNameComp(const std::string &name) : seachname(name)
    {
    }

    bool operator()(const MergeLine * line)
    {
        return seachname.compare( line->linename ) == 0;
    }
};

LL_iter = std::find_if(LineList.begin(), LineList.end(), MergeLineNameCompare(linename) );

(operator ==形式に関係なく) は、等価性を実際に比較するために保存する方が適切です。

于 2013-07-31T22:25:19.693 に答える
0

あいまいであるため、演算子のオーバーロードはポインターでは機能しません。

Bjarne Stroustrup :-

参照は、主に演算子のオーバーロードをサポートするために導入されました。C はすべての関数引数を値で渡します。オブジェクトを値で渡すことが非効率的または不適切な場合、ユーザーはポインターを渡すことができます。この戦略は、演算子のオーバーロードが使用されている場合には機能しません。その場合、オブジェクトが大きい場合にユーザーが演算子のアドレスを挿入することを期待できないように、表記上の利便性が不可欠です。

だから、最高ではないかもしれませんが、それでも:-

   std::vector<MergeLine>LineList;
   std::vector<MergeLine>::iterator LL_iter;
于 2013-07-31T22:49:31.590 に答える