9

次のコードを検討してください。

#include <iostream>
#include <functional>

// passing function object by value
void foo(std::function<int(int, int)> f) {
    std::cout << f(3, 7) << std::endl;
}

// passing const function object by reference
void bar(const std::function<int(int, int)> & f) {
    std::cout << f(3, 7) << std::endl;
}

// passing non-const function object by reference
void fizz(std::function<int(int, int)> & f) {
    std::cout << f(3, 7) << std::endl;
}

int main() {

    std::function<int(int, int)> g1 = [] (int x, int y) { return x * y; };
    auto g2 = [] (int x, int y) { return x * y; };

    foo(g1);   // OK
    foo(g2);   // OK
    bar(g1);   // OK
    bar(g2);   // OK
    fizz(g1);  // OK

    // compile error:
    // error: invalid initialization of reference of type
    // 'std::function<int(int, int)>&' from expression of type
    // 'main()::<lambda(int, int)>'
    // error: in passing argument 1 of 'void fizz(std::function<int(int, int)>&)'
    fizz(g2);

}

誰かが私に説明してくれますか:

(a)fizz(g2)コンパイル エラーが発生し、他の構成では発生しないのはなぜですか? 宣言でその型を明示的に入力すると、参照によってラムダを渡すことができるようですが、autoキーワードを使用する場合、または関数パラメーターの型を として宣言する場合はそうではありませんconst

(b)ここで、関数のパラメーター型の意味は何ですか? const

(c)どのような状況で、参照ではなく値で渡すことを好むでしょうか(更新:別の質問になりました:C++ 11:(ラムダまたはその他の)関数オブジェクトを参照または値で渡しますか?)?

洞察をありがとう。

4

1 に答える 1

10

あなたのfizz(g1)場合、g1はすでにstd::function. したがって、暗黙的な変換は必要ありません。Sofizzのパラメータは、への非 const 参照g1です。

ではfizz(g2)、でg2はありませstd::function。したがって、コンパイラは暗黙的な変換を実行する必要があります。そして暗黙の変換は一時的なを返します。

一時オブジェクトは非 const 参照にバインドできません。const参照または値にのみバインドできます。したがって、コンパイラエラー。

ここで、関数パラメーター型の const とはどういう意味ですか?

オブジェクトのメンバーのみを呼び出すことがconstでき、暗黙的に非に変換することはできず、そのメンバーconstに対して非操作を実行することはできません。const

の他の用途と同様に、 const.

一般的に言えば、関数が const 以外の参照によってパラメーターを取得する場合、そのパラメーターで何をしようとしているのかについて非常に特別なことを言っています。つまり、オブジェクトを渡しており、const 以外の処理 (つまり、そのオブジェクトの変更) を行うということです。そのため、一時変数は非 const 参照にバインドされません。一時的に渡された元のオブジェクトが更新されない可能性があるため、ユーザーの間違いである可能性があります。

が実際fizzにオブジェクトを変更する場合を除き、値または で渡す必要がありますconst&

于 2013-04-13T05:36:10.003 に答える