このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
不適切な値の転送
転送されたオブジェクトが予期せず変更される場合がある
説明
この欠陥は、以下の場合に発生します。
std::move
を使用して、auto&&
型またはT&&
型のオブジェクトを含む、転送参照を関数に転送した場合。std::forward
を使用して、rvalue
参照を関数に転送した場合。
以下のコードについて考えます。関数テンプレート callMethod
では、パラメーター param1
が転送参照で、パラメーター param2
が rvalue
参照です。これらのパラメーターを関数 foo()
に転送すると、コードで誤って転送参照 param1
に対して std::move
が使用され、rvalue
参照 param2
に対して std::forward
が使用されます。
#include<string> #include<iostream> template <class T> class bar{}; template<typename T> void foo(std::string&& s, bar<T>&&){ //... } template <typename T> void callMethod(T&& param1, bar<T>&& param2) { foo(std::move(param1),std::forward<bar<T>&&>(param2)); }
T&&
または auto&&
として宣言され、rvalue
参照は &&
として宣言されます。転送参照と rvalue
参照を混同すると、不適切な値の転送になります。 Polyspace® は、std::move
または std::forward
で参照が関数に転送されなかった場合に、この欠陥を報告しません。たとえば、次のコードは、rvalue
参照 b1
と転送参照 b2
を別の関数に転送しません。std::move
を b2
とともに使用した場合、または std::forward
を b1
とともに使用した場合、欠陥は発生しません。
template <typename T1, typename T2> void func(T1& b1, T2&& b2) { const T1& b10 = std::forward<B>(b1); const T2& b20 = std::forward<B>(b2); const T1& b11 = std::move(b1); const T2& b21 = std::move(b2); }
リスク
std::move
と転送参照をともに使用すると、lvalue が予期せず変更される可能性があります。std::forward
と rvalue
参照をともに使用すると、間違いが生じやすく、コードが複雑になる可能性があります。
修正方法
rvalue
参照を関数に転送する場合は、std::move
を使用して、参照をrvalue
にキャストします。転送参照またはユニバーサル参照を関数に転送する場合は、オブジェクトが
rvalue
に制限される場合にのみ、std::forward
を使用して参照をrvalue
にキャストします。
例
結果情報
グループ: プログラミング |
言語: C++ |
既定値: 手書きコードはオン、生成コードはオフ |
コマンド ライン構文: INCORRECT_VALUE_FORWARDING |
影響度: High |
バージョン履歴
R2020b で導入