2

検討:

#include <vector>

int main()
{
  std::vector <int> v;
  v.reserve (100);
  v[1] = 42;
}

上記のコードが Undefined Behavior を呼び出すことは承知しています。これは、 の呼び出しサイトでv[1]、 によるベクトルのサイズv.size()が < 1 であるためです (ゼロです)。

ただし、これが実際には未定義の動作であることを直接的または間接的に明確にする引用を求めて、C++ 標準に目を通すのに最後の 1 時間ほどを費やしました。

たぶん、私は明らかなことを見逃しています。これを解決するために、少なくとも C++03 およびオプションで C++11 標準からの引用を提供できますか?

4

3 に答える 3

11

それoperator[]は定義方法の結果です。§23.2.3 [sequence.rqmts] 表 101 では、 の操作上のセマンティクスはoperator[]として定義されてい*(a.begin() + n)ます。したがって、イテレータの観点から定義されています。begin過去のインクリメントendと逆参照は、§24.2.1/5 [iterator.requirements.general] によると未定義の動作です。

于 2013-07-18T18:30:19.653 に答える
1

これは根本的な質問には答えませんが、ベクトルのサイズは 0 ではなく、サイズは 100 です (サイズ コンストラクターで作成したため)。

のマニュアルページはstd::vector、それが未定義の動作であると主張していますが、それが「十分」であると考えているかどうかはわかりません(C++標準からの引用を求めました)

template<typename _Tp, typename _Alloc = std::allocator<_Tp>> reference std::vector< _Tp, _Alloc >::operator[] (size_type__n)
   [inline]
   Subscript access to the data contained in the vector. Parameters:
       n The index of the element for which data should be accessed.

   Returns:
       Read/write reference to data.

   This operator allows for easy, array-style, data access. Note that data access with this operator is unchecked and
   out_of_range lookups are not defined. (For checked lookups see at().)

   Definition at line 695 of file stl_vector.h.
于 2013-07-18T18:29:59.523 に答える
0

a[n](ここaで、 はベクトルで、nは整数です) は、23.2.3p16 の表 101 で として定義されてい*(a.begin() + n)ます。

23.3.6.1p1 は、「ベクトル... はランダム アクセス イテレータをサポートする」と述べています。24.2.7p1 の表 111 では、(a + nここaで、 はランダム アクセス反復子) を に関してa += n定義しています。n++a

24.2.3p2 の表 107 では、「逆参照可能」という前提条件で式++r(rは入力反復子) を定義していますr

23.2.1p6 ...end() は、コンテナーの終了値を過ぎた反復子を返します。コンテナーが空の場合、begin() == end() です。

vあなたの例では、実際には空であることに注意してください。これにより証明が簡単になります。operator++そうでなければ、 を繰り返し適用すると が生成v.size()されることを示すために、より多くの引用が必要になります。v.begin()v.end()

24.2.1p5 ...ライブラリは、過去の値が逆参照可能であると想定していません...

于 2013-07-18T18:46:03.020 に答える