1

以下のコードを参照してください (s は、string ではなく char を持つ配列であることに注意してください)。

#include <string>
#include <iostream>
#include <utility>

void func(std::string & s, char a) {
  std::cout << "here1" << std::endl;
  // ...
}

void func(std::string && s, char a) {
  std::cout << "here2" << std::endl;
  // ...
}

template <class T>
void foo(T && s) {
  std::cout << "foo2" << std::endl;
  func(s, ':');
  //func(std::forward<T>(s), ':');
}

int main(int agrc, char *argv[])
{
  //std::string s("a:b:c:d");
  char s[8] = "abcdefg";
  foo(std::move(s));
  std::string s2("abcd")
  foo(s2);
  return 0;  
}

func(s, ':')usingを置き換えても違いはありません。この場合std::forward、foo 関数はなしで完全な転送を行います。std::forward

std::forwardC++11での「prefect forwarding」の誤解はありますか?

4

2 に答える 2

5

それは違いを生みます。あなたの場合、 a を参照するfunc(s, ':')のオーバーロードのみを呼び出します。funcstd::string

std::forward問題は、名前付き変数とパラメーターは左辺値自体であり、これがそもそも存在する理由でもあります。

fooあなたの例では、を使用しなくても、最初の呼び出しで適切なオーバーロードが選択されているように見えますstd::forwardfooこれは、一時的な を暗黙的に構築するために使用されるchar[]引数で実際に呼び出すためですstd::string

于 2014-01-19T17:32:36.267 に答える
1

最初のケースを考えてみましょうfoo(std::move(s))。の中でfoos右辺値にバインドされます。しかし、名前 ( s) があるため、もはや右辺値ではありません。したがって、それに渡すsfunc、左辺値を渡すようになります-here1バージョンがトリガーされます。ただし、s経由std::forwardする場合は、再び右辺値になります。

2 番目のケースsは foo が入力されたときの左辺値参照であるため、直接渡しても 経由しても何も変わりませんstd::forwardstd::move右辺値をs再度取得するには、使用する必要があります。

于 2014-01-19T17:35:07.010 に答える