2009-03-29 14 views
4

関数オブジェクトを渡す次の小さなプログラムで何が問題になっていますか?関数オブジェクトを渡す:エラー

#include <iostream> 
#include <functional> 

void foo(const std::unary_function<const std::string&, void>& fct) { 
    const std::string str = "test"; 
    fct(str); // error 
} 

class MyFct : public std::unary_function<const std::string&, void> { 
public: 
    void operator()(const std::string& str) const { 
    std::cout << str << std::endl; 
    } 
}; 

int main(int argc, char** argv){ 
    MyFct f; 
    foo(f); 
    return 0; 
} 

私は6行目に次のエラーを取得しています:

no match for call to 
`(const std::unary_function<const std::string&, void>) (const std::string&)' 

答えて

11

よくある間違いを。 unary_functionbinary_functionはtypedefの

argument_type 
result_type 

それぞれ

first_argument_type 
second_argument_type 
result_type 

ない以上を追加ちょうど2つの構造体です。関数オブジェクト型の作成者の便宜のためであり、それらは自分で行う必要はありません。しかし、彼らは多態性を行動しません。あなたが望むものは、関数オブジェクトラッパーです。 boost::functionが頭に浮かぶ:

void foo(boost::function<void(const std::string&)> const& fct) { 
    const std::string str = "test"; 
    fct(str); // no error anymore 
} 

それとも、あなたは値によってそれを取ると、その後いくつかのシーケンスに適用するためにそれを使用する場合fooからコピーを返すことができますテンプレート

template<typename FunctionObject> 
void foo(FunctionObject const& fct) { 
    const std::string str = "test"; 
    fct(str); // no error anymore 
} 

します。これは、関数オブジェクトがメンバー間でいくつかの状態変数を更新できるようにします。 for_eachはそのような例です。とにかく、私はそれらが通常小さいので、価値を受け入れ、それらをコピーすることで大きな柔軟性が得られます。だから私は

template<typename FunctionObject> 
void foo(FunctionObject fct) { 
    const std::string str = "test"; 
    fct(str); // no error anymore 
} 

は、あなたが、その後、FCTのコピーを取り、どこかに保存することができますし、fctのオペレータは()非constにすることができ、全体のポイントの一部である(一部のメンバーを更新しませんoperator())。あなたが関数参照を使って関数オブジェクトを受け取った場合、その関数オブジェクトを渡すことができるので、一般的にそれをコピーすることはできません。それをコピーすると、ローカル関数ポインタの代わりに関数をローカルに宣言しようとします。ただし、by-valueを受け入れると、関数が渡されたときに代わりに関数ポインタを受け取り、安全にコピーできます。

+0

ありがとうございます!ブーストソリューションはテンプレートソリューションほど効率的ですか? – Frank

+0

ブースト・ソリューションは、ラップされた関数オブジェクトへの間接呼び出しを行う必要があるため効率的ではありません(それはそれ自身のvtableを作成します)。しかし、それはあなたがテンプレートを必要としないという利点があります。そのboost.functionを使用して、どこかに格納することができます(クラスメンバーなど)。 –

+0

私はあなたがunary_functionで探していたものに最も近いと思います –

関連する問題