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\functional 296

私が間違っていることと、それを修正する方法を教えてください。

4

3 に答える 3

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

編集

不注意な方への注意: Pointer Container ライブラリは、インターフェイスが可能な限り使いやすいように設計されています。利点の 1 つは、二重の逆参照を行う必要がないことです。これはコンパイルされます:

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

 int& i = *vec.begin();

したがって、ファンクターはポインターではなく参照を取る必要があります:)

于 2010-06-24T09:52:31.650 に答える
1

完全を期すために、次のステートメントは間違っています。私の間違いを指摘してくれた Matthieu M. に感謝します!

ブースト ポインター コンテナーのイテレーターを逆参照すると、要素への純粋なポインターが取得されます。したがって、イテレータを介して取得した純粋なポインタを逆参照することができます。

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

以下はまだ正しいです;)

または、要素への参照を返すのoperator[]実装を使用できます。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])
  );
}

お役に立てれば。

于 2010-06-24T09:00:12.027 に答える
0

申し訳ありませんが、いくつかの理由で、以前の投稿にコメントを追加できなかったので、回答として書いています。

両方の方法を試しました。最初のものは、違法な間接化です。

2 番目のエラーについては、同じエラーが表示されます。詳細な出力では、詳細は次のようになります。

c:\program files\microsoft visual studio 9.0\vc\include\functional(296): エラー C2440: '初期化中': 'const CMDatabase::Try' から 'CMDatabase::Try *' に変換できませんこの変換を実行できる変換演算子が使用可能であるか、演算子を呼び出すことができません 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, _Result=bool, _Ty=CMDatabase::Try, _Arg=CMDatabase::TryPtr ] でコンパイルされています

于 2010-06-24T09:13:19.967 に答える