メインコンテンツ

AUTOSAR C++14 Rule A18-9-2

Forwarding values to other functions shall be done via:(1) std::move if the value is an rvalue reference, (2) std::forward if the value is forwarding reference

説明

ルール定義

Forwarding values to other functions shall be done via:(1) std::move if the value is an rvalue reference, (2) std::forward if the value is forwarding reference.

根拠

オブジェクトを rvalue にキャストし、移動セマンティクスを利用することによって、オブジェクトを効率的に関数に渡すことができます。

  • rvalue 参照を関数に転送する場合は、std::move を使用してオブジェクトを右辺値にキャストします。

  • 転送参照 (またはユニバーサル参照) を関数に転送する場合は、オブジェクトが rvalue に制限される場合にのみ、std::forward を使用してオブジェクトを右辺値にキャストします。転送参照は、rvalue または lvalue に制限される可能性があります。このルールのため、auto && 型のオブジェクトは転送参照と見なされます。

std::move と転送参照を使用すると、lvalue が予期せず変更される可能性があります。std::forward と rvalue 参照を使用できますが、ミスが発生しやすく、コードが複雑になる可能性があります。

Polyspace 実装

  • Polyspace® は、auto && 型のオブジェクトを含む、転送参照を関数に転送するための std::move の使用にフラグを設定します。

  • Polyspace は、rvalue 参照を関数に転送するための std::forward の使用にフラグを設定します。

  • Polyspace は、関数への転送が実行されない場合は、std::move または std::forward の使用にフラグを設定しません。たとえば、このコード スニペットでは、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);
    }

トラブルシューティング

ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

#include <cstdint>
#include <string>
#include <utility>


class A
{
public:
    explicit A(std::string&& s)
        : str(std::move(s)) // Compliant
    {
    }

private:
    std::string str;
};

template <typename ...T>
void f1(T...t);



template <typename T1, typename T2>
void func(T1&& t1, T2& t2)
{
    f1(std::move(t1));            // Non-compliant
    f1(std::forward<T1>(t1));     // Compliant

    f1(std::forward<T2>(t2));     // Non-compliant
    f1(std::move(t2));            // Compliant
}

void func_auto(A& var)
{
    auto&& var1 = var;
    f1(std::move(var1));                    // Non-compliant
    f1(std::forward<decltype(var1)>(var1)); //Compliant
}

void main()
{
    int32_t i;
    func(0, i);
}

この例では、テンプレート関数 func がパラメーターの t1t2 を関数 f1 に転送します。Polyspace は、std::forwardt2 の使用にフラグを設定します。これは、このパラメーターがrvalue 参照 (T& 型) であるためです。

Polyspace は、std::movet1 の使用にもフラグを設定します。これは、このパラメーターが転送参照 (T&& 型) であるためです。t1 が lvalue で初期化される場合は、移動によってパラメーターが予期せず変更される可能性があります。同様に、Polyspace は、func_auto 内の std::move の使用にフラグを設定します。これは、auto&& 型のオブジェクトが転送参照と見なされるためです。

チェック情報

グループ: 言語サポート ライブラリ
カテゴリ: Required、Automated

バージョン履歴

R2020b で導入