次の構造のコードが与えられた場合
_template <typename... Args>
void foo(Args&&... args) { ... }
_
ライブラリコードは、引数の転送のために関数内で_static_cast<Args&&>
_を使用することがよくあります。通常、これを正当化する理由は、_static_cast
_を使用すると、不要なテンプレートのインスタンス化が回避されるということです。
言語の参照の折りたたみとテンプレートの控除ルールを考えます。 _static_cast<Args&&>
_で完全な転送を取得します。この主張の証拠は以下にあります(エラーマージン内で、答えが明らかになることを望んでいます)
&& &&
_-> _&&
_(上記のルール_1
_)& &&
_-> _&
_(上記のルール_2
_)これは本質的に、上記の例でfoo()
に引数をbar()
に転送させることです。これは、ここで_std::forward<Args>
_を使用した場合に得られる動作です。
質問-なぜこれらのコンテキストで_std::forward
_を使用するのですか?余分なインスタンス化を避けることは、慣例に違反することを正当化しますか?
Howard Hinnantの論文 n2951 は、_std::forward
_の実装が「正しく」動作する6つの制約を指定しました。これらが
(1)および(2)は、上記の_static_cast<Args&&>
_で正しく動作することが証明されました。 (3)-(6)ここでは当てはまりません。関数が演contextされたコンテキストで呼び出されると、これらのいずれも発生しないためです。
注:私は個人的に_std::forward
_を使用することを好みますが、私が持っている正当化は純粋に慣習に従うことを好むということです。
ここに私の2.5がありますが、これはそれほど技術的なセントではありません。今日std::forward
が実際に単なるstatic_cast<T&&>
であるという事実は、明日もまったく同じ方法で実装されることを意味しません。委員会は、std::forward
が今日達成することの望ましい振る舞いを反映するために何かを必要としていたので、どこにも転送しないforward
が存在するようになったと思います。
理論的に言えば、std::forward
の傘下で必要な動作と期待を形式化すると、将来の実装者がstd::forward
ではなく、自分の実装に固有の何かとしてstatic_cast<T&&>
を提供することを妨げません。重要なのはstatic_cast<T&&>
の正しい使用法と動作だけであるため、実際にstd::forward
を考慮せずに.