15

C++ 標準の std::function<>::operator() の定義が次の理由:

R operator()(ArgTypes...) const;

ではない

R operator()(ArgTypes&&...) const;

?

パラメータを正しく転送するには、 && が必要でありstd::forward<ArgTypes>...、呼び出しを転送するときに関数本体で使用すると思いますか?

これをテストするために std::function を部分的に再実装しましたが、&& を使用すると、後でパラメーターを値で operator() に渡そうとすると、g++ から「'xxx' 左辺値を 'xxx&&' にバインドできません」というメッセージが表示されることがわかりました。 . 右辺値/転送の概念については十分に理解できたと思いますが、まだこの点を理解できていません。私は何が欠けていますか?

4

1 に答える 1

17

完全転送は、関数自体 (この場合operator()は ) がテンプレート化され、テンプレート引数が推定される場合にのみ機能します。の場合、クラス自体のテンプレート パラメーターから引数の型std::functionを取得します。つまり、どの引数からも型が推測されることはありません。operator()

完全転送の背後にある全体のトリックは、テンプレートの引数推定部分であり、参照の崩壊とともに、完全転送とは何かです。

ここで、完璧な転送(および)がどのように機能するかを説明する他の回答std::forwardに簡単にリンクしますstd::forward

std::functionユーザー自身がパラメータがどうあるべきかを決定するので、 は完全な転送を必要とoperator()しないことに注意してください。これは、単に;に追加&&できない理由でもあります。operator()この例を見てください:

void foo(int){}

int main(){
  // assume 'std::function' uses 'ArgTypes&&...' in 'operator()'
  std::function<void(int)> f(foo);
  // 'f's 'operator()' will be instantiated as
  // 'void operator()(int&&)'
  // which will only accept rvalues
  int i = 5;
  f(i); // error
  f(5); // OK, '5' is an rvalue
}
于 2012-06-21T10:00:48.120 に答える