64

を使用std::bindしてメンバー関数をバインドする場合、最初の引数はオブジェクトthisポインターです。ただし、オブジェクトをポインターとして渡す場合とそうでない場合の両方で渡すことは機能します。

たとえば、次のプログラムを参照してください。

#include <iostream>
#include <functional>

struct foo
{
    void bar(int v) { std::cout << "foo::bar - " << v << '\n'; }
};

int main()
{
    foo my_foo;

    auto f1 = std::bind(&foo::bar, my_foo, 1);
    auto f2 = std::bind(&foo::bar, &my_foo, 2);

    f1();
    f2();
}

clang と GCC の両方がこれを問題なくコンパイルし、結果は両方のバインドで機能します。

フー::バー - 1
フー::バー - 2

私は仕様 (セクション 20.8.9) に頭を悩ませようとしてきましたが、それは私には明確ではない場所の 1 つです。

どちらか一方だけが正しいか、両方が正しいか。

4

3 に答える 3

51

どちらも正しいです。20.8.9.1.2 から 20.8.2 に転送して、 への呼び出しの要件と効果を説明しますbind。20.8.2 は次のとおりです。

20.8.2 要件 [func.require]

1 INVOKE(f, t1, t2, ..., tN)を次のように定義します。

(t1.*f)(t2, ..., tN)fクラスのメンバ関数へのポインタでありTt1Tのオブジェクト、型のオブジェクトへのT参照、または から派生した型のオブジェクトへの参照である場合T

((*t1).*f)(t2, ..., tN)fクラスのメンバ関数へのポインタでありTt1前の項目で説明した型のいずれでもない場合。

—およびt1.*fがクラスのメンバ データへのポインタであり、が型のオブジェクト、または型のオブジェクトへの参照、または から派生した型のオブジェクトへの参照である場合。N == 1fTt1TTT

— and(*t1).*fがクラスのメンバ データへのポインタであり、前の項目で説明した型のいずれでもない場合。N == 1fTt1

f(t1, t2, ..., tN)その他のすべての場合。

最初の 2 つのオプションは、参照とポインターの両方を許可します。

ここで注目すべき重要なことは、文言が単純なポインターに限定されないということです。またはその他のスマート ポインターを使用std::shared_ptrして、バインドされている間もインスタンスを存続させることができます。インスタンスが何であれ、逆参照std::bindされたままでも機能します (もちろん、それが可能である場合)。t1

于 2013-03-07T05:56:05.140 に答える