1. ホーム
  2. c++

[解決済み] std::forwardを使用して引数を転送するタイミングは?

2022-04-26 05:31:15

質問

C++0xでは std::forward :

template<class T>
void foo(T&& arg) 
{
  bar(std::forward<T>(arg));
}

を使うのが有利なのはどんな場合ですか? std::forward 常にですか?

また && をパラメータ宣言に使用することができますが、これはすべてのケースで有効なのでしょうか?関数にテンポラリを渡すには、関数が && ということは、fooはどんなパラメータでも呼び出せるのでしょうか?

最後に、このような関数呼び出しがあった場合。

template<int val, typename... Params>
void doSomething(Params... args) {
  doSomethingElse<val, Params...>(args...);
}

代わりにこれを使うべきでしょうか。

template<int val, typename... Params>
void doSomething(Params&&... args) {
  doSomethingElse<val, Params...>(std::forward<Params>(args)...);
}

また、関数内でパラメータを2回使用する場合、つまり、2つの関数に同時に転送する場合にも、以下のようにするのが賢明でしょうか? std::forward ? となります。 std::forward は、同じものを2回一時的に変換し、メモリを移動させ、2回目の使用は無効とするのでしょうか?以下のようなコードで大丈夫でしょうか。

template<int val, typename... Params>
void doSomething(Params&&... args) {
  doSomethingElse<val, Params...>(std::forward<Params>(args)...);
  doSomethingWeird<val, Params...>(std::forward<Params>(args)...);
}

で少し混乱しています。 std::forward ということです。

解決方法は?

最初の例と同じように使ってください。

template <typename T> void f(T && x)
{
  g(std::forward<T>(x));
}

template <typename ...Args> void f(Args && ...args)
{
  g(std::forward<Args>(args)...);
}

それは 参照コラプシングルール : もし T = U& であれば T&& = U& が、もし T = U&& であれば T&& = U&& そのため、関数本体の内部には常に正しい型が存在することになります。最後に forward を、L値化された x (名前がついたので!) 最初はrvalueの参照であった場合は、rvalueの参照に戻してください。

しかし、何かを2回以上転送することは、通常は意味を成しません。転送するということは、潜在的に 移動 そして、一度移動した引数は消えてしまうので、(おそらくあなたが意図した方法で)再び使用することはできません。