2

有効な C++の項目 3から

/* case1 */ const std::vector<int>::iterator i  // i  acts like a T* const
/* case2 */ std::vector<int>::const_iterator ci // ci acts like a const T*

どのようconstに適用されるかを覚えておくために、私はこの記事から次のことを覚えていました

基本的に、'const' はそのすぐ左にあるものに適用されます (何もない場合を除き、そのすぐ右にあるものに適用されます)。

本の項目 3 を最初に読んだとき、ケース 1 とケース 2 で逆になると思っていました。

このケースは例外として扱うべきですか? それとも、私が見逃しているより深いレベルの理解がありますか?

4

5 に答える 5

8

ルールはアドバタイズされたとおりに機能します。

const std::vector<int>::iterator i

すぐ右側の項目はiterator次のとおりです。イテレータは不変です。ベクトル内の異なるアイテムを指すようにイテレータを割り当てることはできません。インクリメントすることはできません。常に初期化されるアイテムを指します。ただし、ポイントするアイテムは変更できます。

これが望ましい動作になることはめったにありません。そのため、const_iteratortypedefが存在します。

std::vector<int>::const_iterator ci

イテレータは移動できますが、ポイントされたアイテムは変更できません。これはほとんどの場合、必要なものです。ベクトルを反復処理したいが、その内容を変更することはできません。

ここにはconstキーワードがないため、ルールを使用してそれを理解することはできません。const_iteratorこれについては、文書化されていることを理解する必要があります。

于 2010-07-25T18:09:55.243 に答える
5

typedefイテレータが次のように編集されたかのように考えることができます。

typedef T* iterator;
typedef const T* const_iterator;

これらのいずれかに追加すると、トップレベルconstに適用されます。つまり、ポイントされたオブジェクトではなく、ポインタ自体に適用されるため、次の同等性が成り立ちます。

const iterator it; // is the same as:
T* const it;

const const_iterator it; // is the same as:
const T* const it;

それらも例外ではありません。これがすべての仕組みtypedefです。

于 2010-07-25T18:09:46.530 に答える
1

const引用されたルールは、キーワードに完全に当てはまります。ただし、イテレータを処理する場合、const_iteratorクラスは単にそのように名前が付けられているため(同じようにreadonly_iterator)、constキーワードに関する規則は適用されません。

ただし、次のようにケース1を宣言できます。

std::vector<int>::iterator const i

const int xまたはを指定できるのと同じですint const x

イテレータが指すタイプは、そのコンテナのテンプレートパラメータでも指定されるため、順序は通常の変数の宣言とは異なります。

ここで従うべき特定の経験則があることはわかりません。投稿内のコメントは正しい考えであり、次のように扱うことを学ぶ必要がありconst_iteratorますconst T*

于 2010-07-25T18:08:45.807 に答える
1

const_iteratorがあなたを混乱させていると思います。これは、より単純なtypedefの例です。

typedef int* Type;
typedef const int* ConstType;

int main() {
  const Type a; // int * const
  ConstType b; // const int *
}
于 2010-07-25T18:11:56.727 に答える
0

ケース1はconstイテレータに適用されるため、イテレータ自体が定数になります。イテレータが「指している」アイテムには影響しません。(これはのようにT* const、ポインタはconstであり、ポイントされていませんT

ケース2の場合、constは名前の一部にすぎconst_iteratorないため、そこに何があるかを実際に推測することはできませんconst。クラスの名前が間違っている可能性があり、それについて何も問題がない可能性があります。ただし、この場合const_iterator、標準ライブラリでそのように定義されているため、ターゲット要素の変更は許可されません。

于 2010-07-25T18:15:27.413 に答える