2012-03-02 10 views
1

以下にコメントしてくれてありがとう。ポインタのリストへのメンバー関数

Class1 { debug(std::ostream&){} }; 
int main() { 
    std::vector<Class1*> list1; 
    // some work to do 
} 

ターゲットプラットフォーム:

  • プラットフォーム(1):ウィン7x64、VS2010
  • プラットフォーム(2)のLinux X32、G ++ 4.4

Q:次のステートメントに "std :: cout"を渡す正しい方法は何でしょうか?

std::for_each(list1.begin(), 
       list1.end(), 
       "afunction(&Class1::debug, std::cout)"); 

私は以前にデバッグ()関数内「のstd :: coutを」を使用しますが、後でデバッグメッセージを出力するための柔軟性を与えることを検討してください。

編集:その他の情報:ファンクタオブジェクトがある場合は、複数のクラスに対応するためにファンクタを実装する必要があります(これらのクラスは同じ「デバッグ」関数の署名以外の関係はありません)。

Edit(2): "std :: for_each"を使用すると、各クラスの対応するデストラクタを直接呼び出してlist1のすべてのオブジェクトを破棄することは可能ですか? (例えばfor_each(l.begin()、l.end()、 "クラス::〜のClass1");

編集(3): "PMR" あたりが示唆したように、私は

std::for_each(l.begin(), 
       l.end(), 
       std::bind2nd(std::mem_fn(&Class1::debug), out)); 
として声明を作ります

これは、コンパイルし、Linuxプラットフォーム上で正しく実行されますが、VS2010、Class1のためのコードで失敗しました::デバッグは

void Class1::debug(const std::ostream& out) 
{ 
    out << "some text" << someVar << "some text" << std::endl; 
} 

VSエラーMSGが

エラーC2678です:バイナリ '< <':オペレーターなし'const std :: ostream'型の左辺オペランドを取るatorが見つかりました(または受け入れ可能な変換はありません)

キューはありますか?

[閉] 私のクラスにオーバーロードされた演算子< <が実装され、デバッグプリント機能の使用が閉じられました。すべてのヒントを与えてくれてありがとう。

答えて

1

あなたが最初の選択となるラムダ式を使用することはできませんグラム++ 4.4を使用しているので(それ以降のバージョンがそれらをサポートする、MSVCは同様に行います)。

したがって、ファンクタが必要です。ファンクタは関数オブジェクトであり、それはoperator()を実装するクラス(または構造体)です。

Debug d(cout); 
std::for_each(list1.begin(), list1.end(), d); 
0

は、関数ポインタの代わりにラムダを使用します。これはC++ 11xの機能であり、コンパイラがラムダを認識するためのフラグを含める必要があります。

std::for_each(list1.begin(), list1.end(), [&debug, &cout] 
{ 
// implementaion 
} 
); 
0

GCC 4.5までラムダをサポートしていませんので、明確な解決策は論外である。このような

class Debug 
{ 
public: 
    Debug(ostream& os) : _os(os) 
    { } 

    void operator()(Class1* instance) 
    { 
      // will print the pointer, replace with user code 
      os << instance << endl; 
    } 
private: 
    ostream& _os; 
}; 

を使用:このように。あなたは、一般的なアルゴリズムの多くを使用したい

秒最も簡単な解決策はBoost.Lambda http://www.boost.org/doc/libs/1_49_0/doc/html/lambda.htmlです:

for_each(list1.begin(), list.end(), _1->debug(cout)); 

そして最後に、退屈な関手ソリューション:個人的に

class Output 
{ 
public: 
    explicit Output(ostream& ios) : os(&ios) 
    { 
    } 

    void operator()(Class1* obj) 
    { 
      obj->debug(*os); 
    } 

private: 
    ostream* os; 
}; 
for_each(list1.begin(), list1.end(), Output(cout)); 

私はと思いますC++ 11ラムダやBoost Lambdasなしでは、for_eachはそれ以上の価値があります。

for (vector<Class1*>::iterator it = list1.begin(); it != end; ++it) 
    (*it)->debug(cout); 
0

C++ 03:だけでなく、単純なループを行う可能性があります

#include <vector> 
#include <functional> 
#include <iostream> 
#include <algorithm> 

struct Foo { 
    void debug(std::ostream&) {} 
}; 

int main() 
{ 
    std::vector<Foo*> foos; 
    std::for_each(foos.begin(), foos.end(), 
       std::bind2nd(std::mem_fun(&Foo::debug), std::cout)); 
    return 0; 
} 

バインダーが推奨されておらず、boost::bindまたは C++ 11が支持されるべきであることに注意してください。実際には、新しいコンパイラが必要です。

+0

私はMS VS2010でエラー "C2678:binary '<<'が見つかりませんでした:いくつかのポイントにコンパイルしましたが、 'const std :: ostream '(あるいは受け入れ可能な変換はありません) –

+0

私のコード例では、operator <<を見ることができません。おそらくあなたは出力を行う方法に問題があります。 'ostream'を' const& 'ではなく'& 'で取ってください。これで解決するはずです。 – pmr

関連する問題