メインコンテンツ

AUTOSAR C++14 Rule A23-0-1

An iterator shall not be implicitly converted to const_iterator

説明

ルール定義

反復子は暗黙的に const_iterator に変換しないものとします。

根拠

C++11 標準では、cbegincend などの const 反復子をコンテナーに返すメンバー関数が導入されました。const 反復子を作成するには、beginend などの非 const 反復子を返し、暗黙的な変換が必要な関数の代わりに、これらのメンバー関数を使用します。

たとえば、std::list コンテナーを考えてみましょう。

std::list<int> aList = {0, 0, 1, 2};
コンテナーの begin メンバー関数と end メンバー関数を使用して、for ループ内などで、const 反復子を作成できます。
for(std::vector<int>::const_iterator iter{aList.begin()}, end{aList.end()};
    iter != end;
    ++iter) {...}
ただし、関数の beginend は非 const 反復子を返すため、const 反復子の iterend への代入で、暗黙的な変換が行われる必要があります。代わりに、const 反復子を直接返す、新しい C++11 関数の cbegincend を利用してください。
for(std::vector<int>::const_iterator iter{aList.cbegin()}, end{aList.cend()};
    iter != end;
    ++iter) {...}
これらの関数を使用すると、反復子の明示的な型指定を auto で置き換えることもできます。
for(auto iter{aList.cbegin()}, end{aList.cend()};
    iter != end;
    ++iter) {...}

Polyspace 実装

チェッカーは、iterator 型から const_iterator への変換、または reverse_iterator から const_reverse_iterator への変換にフラグを設定します。

トラブルシューティング

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

すべて展開する

#include <cstdint>
#include <vector>

void func(std::vector<int32_t> & values, int32_t aValue) {
    std::vector<int32_t>::const_iterator iter1 = 
                  std::find(values.begin(), values.end(), aValue); //Noncompliant
    std::vector<int32_t>::const_iterator iter2 = 
                  std::find(values.cbegin(), values.cend(), aValue);  //Compliant
}

この例では、1 つ目の std::find 関数呼び出しで、std::vector コンテナー valuesbegin メソッドと end メソッドの戻り値が引数として使用されます。これらのメソッドは、std::vector<intr32_t>::iterator 型の反復子を返します。std::find テンプレートの戻り値の型が最初の 2 つの引数の型と同じであるため、このテンプレートも std::vector<intr32_t>::iterator 型の反復子を返します。この戻り値が std::vector<intr32_t>::const_iterator 型の変数に代入されれば、暗黙的変換になります。

2 つ目の呼び出しでは、std::vector<intr32_t>::const_iterator 型の反復子を返す cbegin メソッドと cend メソッドが使用され、暗黙的変換が回避されます。

チェック情報

グループ: コンテナー ライブラリ
カテゴリ: Required、Automated

バージョン履歴

R2020a で導入