13

std::bindN3225のサブセクションの説明を読んで行き詰まってい20.8.10.1ます。以下は印刷する必要があると書かれていますが、それはその引数をコピーすることになっているので、印刷する必要1があると思いました。渡された引数を参照したい場合は、を使用する必要がありますよね?bind0std::ref

void f(int &a) { a = 1; }

int main() {
  int a = 0;
  std::bind(f, a)();
  std::cout << a << std::endl;
}

GCCの出力0は、私が物事がうまくいくと思ったことに同意します。しかし、N3225は、std::bind(f, a1)によって呼び出されたときに、を呼び出す呼び出しラッパーを返すと言っていwrapper()ますINVOKE(f, v1)。ここで、 (v1aが渡した引数、つまり、binds完全な転送パラメーターであるの着信パラメーターを使用しますstd::forward<A1>(a1))。

INVOKE(f, a)20.8.2から。で定義されf(a)ます。したがって、これは、返された呼び出しラッパーへの呼び出しが元の引数を渡すことを定義します。私は何が欠けていますか?

4

3 に答える 3

5

次のように印刷する必要があります1

いいえ、それは言いません。

渡された引数を参照したい場合は、std :: refを使用する必要がありますよね?

はい。

しかし、N3225は、std :: bind(f、a1)は、wrapper()によって呼び出されたときにINVOKE(f、v1)を呼び出す呼び出しラッパーを返すと述べています。ここで、v1は(私が渡した引数、つまり、完全な転送パラメーターであるbindsの着信パラメーターstd::forward(a1​​)を使用します。

それはあなたが間違っているところです。TiDbind-callで渡された「バインドされた引数」は、それぞれがから構築されたタイプの新しく作成されたオブジェクトの形式で格納されますforward<Ti>(ti)。これは、「tidはから構築されたタイプTiDの左辺値です」と言うことでかなり明確になりstd::forward<Ti>(ti)ます。参照ラッパーの特別な処理により、追加の「変換レイヤー」があります。およびにどのようviVi関連するかを説明する20.8.10.1.2/10を参照してください。tidTiD

于 2011-02-21T14:11:54.040 に答える
3

std :: bindを呼び出した時点では、参照を渡したいことがわからないため、現在は0が出力されます。関数のシグニチャを調べて、必要なパラメータタイプを確認し、それに応じて調整することはありません。

正しく動作させるには、

void f(int &a) { a = 1; }

int main() {
  int a = 0;
  std::bind(f, std::ref(a))();
  std::cout << a << std::endl;
}

C ++ 0xは「完全なバインディング」を示唆していますが、これには大きな危険があり、現在の動作に依存する既存のコードを黙って壊してしまう可能性があります。これは非常に簡単な例です。

void myCallback( const std::string& str, int i );

function< void(int) > makeCallback( const std::string & str )
{
    return bind( myCallback, str, _1 );
}

現在、渡した文字列をバインドコピーすることに依存できるためstr、コールバックの呼び出しによって有効になるという事実があります。

「完全なバインディング」を「スマートに」使用して参照として保存すると、このような状況が発生しなくなります。

于 2011-02-21T13:14:18.127 に答える
2

うわー、これは信じられないほど混乱しています。これは、次のように定義v1されtidます(tii番目の完全な転送バインドパラメーターでありTiD、そのパラメーターの減衰タイプです。つまり、配列がポインターになるなど)。

tidTiDから構築された型の左辺値ですstd::forward<Ti>(ti)

さて、私は言いました、これtidはそうですstd::forward<Ti>(ti)、そしてそれは左辺値です!しかし、これは実際に言うことの意味ではありません。その意味は

tidTiDから構築されたオブジェクトを参照する型の左辺値ですstd::forward<Ti>(ti)

今ではもっと理にかなっています。std::forward<Ti>(ti)実際に右辺値である場合はどうなるのでしょうか。「...から構築された左辺値...」は、「...」から新しいオブジェクトを作成し、左辺値がそれを参照するようにすることを意味します。

于 2011-02-21T11:26:12.287 に答える