Cの完全な転送は、元の値カテゴリ(LValueまたはRValue)とタイプを維持しながら、ある関数から別の関数に引数を渡すことを可能にする手法です。これは、元の呼び出しの効率とセマンティクスを保持する方法で、他の関数に引数を転送する必要があるテンプレート関数を作成する場合に特に役立ちます。
完全な転送は、参照崩壊とstd::forward
を組み合わせて機能します。これがどのように動作しますか:
T& &&
)へのRValue参照はLValue Reference( T&
)に崩壊し、その他の組み合わせ( T&& &&
またはT& &
)は、最も内側の参照のタイプに崩壊します。T&&
を使用して達成されます(通常はauto&&
またはテンプレートパラメーターを使用)。std::forward
ユーティリティは関数内で使用され、引数を別の関数に転送し、値カテゴリを保存します。 std::forward<t>(arg)</t>
を使用すると、 T
がlvalue参照の場合、またはT&&
T
がrvalue参照の場合はT
にarg
をキャストします。これが完璧な転送を示す簡単な例です。
<code class="cpp">template<typename t> void wrapper(T&amp;& arg) { // Forward 'arg' to another function, preserving its value category anotherFunction(std::forward<t>(arg)); } void anotherFunction(int& arg) { /* lvalue overload */ } void anotherFunction(int&& arg) { /* rvalue overload */ } int main() { int x = 5; wrapper(x); // Calls anotherFunction(int&) because x is an lvalue wrapper(5); // Calls anotherFunction(int&&) because 5 is an rvalue return 0; }</t></typename></code>
この例では、 wrapper
完全な転送を使用してarg
anotherFunction
に渡すために、元の引数の値カテゴリに基づいてanotherFunction
を過負荷にします。
Cで完全な転送を使用することの利点は次のとおりです。
完全な転送は、いくつかの方法で、Cのテンプレート関数の効率を大幅に改善できます。
これは、完全な転送が効率を改善できることを示す例です。
<code class="cpp">template<typename t> void efficientWrapper(T&amp;& arg) { std::vector<int> v(std::forward<t>(arg)); // Efficiently constructs v from arg } int main() { std::vector<int> source = {1, 2, 3}; efficientWrapper(std::move(source)); // Moves the contents of source into v return 0; }</int></t></int></typename></code>
この例では、 efficientWrapper
完全な転送を使用して、 arg
からv
効率的にVを構築します。 arg
( main
関数のように)rvalueである場合、Moveセマンティクスを使用して不必要なコピーを避けます。
Cで完全な転送を実装するとき、認識して避けるべきいくつかの一般的な落とし穴があります。
std::forward
: std::forward
の誤った使用は、元々転送リファレンスを取得した関数内でのみ使用する必要があります。このコンテキストの外でそれを使用すると、動作が誤っています。たとえば、メンバー変数に転送リファレンスを保存してから後で転送すると問題を引き起こす可能性があります。T&amp; &&
T&
に崩壊する一方で、 T&& &&
T&&
に崩壊することを常に覚えておいてください。一般的な落とし穴の例とそれを回避する方法は次のとおりです。
<code class="cpp">// Incorrect use of std::forward class IncorrectUsage { template<typename t> void incorrectForward(T&amp;& arg) { store = std::forward<t>(arg); // Incorrect: don't use std::forward here } std::string store; }; // Correct use of std::forward class CorrectUsage { template<typename t> void correctForward(T&amp;& arg) { store = std::forward<t>(arg); // Correct: use std::forward immediately } std::string store; };</t></typename></t></typename></code>
IncorrectUsage
クラスでは、 std::forward
が保存されたメンバー変数で使用され、動作が誤っている可能性があります。 CorrectUsage
クラスでは、 std::forward
関数内ですぐに使用され、引数の正しい値カテゴリを保存します。
これらの落とし穴を認識し、ベストプラクティスに従うことにより、完璧な転送を効果的に使用して、より効率的で正しいCコードを書き込むことができます。
以上がCの完全な転送とは何ですか?それはどのように機能しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。