5

std::reference_wrapperデフォルトでは構築可能ではありません。したがって、次のいずれも書くことができません。

std::vector<std::reference_wrapper<int>> vec(10);
std::array<std::reference_wrapper<int>, 3> arr;

しかし、驚いたことに、オブジェクトstd::vector::reserveのベクトルのメンバー関数を呼び出して、std::reference_wrapperその容量を効果的に変更できます。

std::vector<std::reference_wrapper<int>> vec;  
vec.reserve(10);

ライブデモ

std::reference_wrapperデフォルトのコンストラクターがないため、これはどのように可能ですか?

4

3 に答える 3

3

SGI STL実装を参照できます

stl_vector.h で:

void reserve(size_type __n) {
    if (capacity() < __n) {
      const size_type __old_size = size();
      iterator __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
      destroy(_M_start, _M_finish);
      _M_deallocate(_M_start, _M_end_of_storage - _M_start);
      _M_start = __tmp;
      _M_finish = __tmp + __old_size;
      _M_end_of_storage = _M_start + __n;
    }
  }

void resize(size_type __new_size) { resize(__new_size, _Tp()); }

reserve は新しい要素を作成しませんが、サイズ変更は行います。

于 2016-05-18T14:50:10.217 に答える
2

vector::reserve(N)N要素のストレージ容量を事前に割り当てるだけです。使用しているベクター コンストラクターは「デフォルトの塗りつぶし」コンストラクターです。デフォルト コンストラクター要素を作成 Nし、コンテナーに挿入します。

例えば

vector<T> v;
v.reserve(N);
assert(0 == v.size());
assert(N >= v.capacity());

vector<T> v(N);
assert(N == v.size());
assert(N >= v.capacity());

C++17 ワーキング ドラフトの 23.3.6.3.p2 [vector.capacity] によると、必要vector::reserve()なのTは. 問題のコンストラクターは 23.3.6.2.p3 [vector.cons] で指定されており、それがintoである必要があります。MoveInsertable*thisTDefaultInsertable*this

reference_wrapper<>そうではありMoveInsertableませんDefaultInsertable(あなたが述べたように、デフォルトで構築することはできません)。これらの概念の正確な定義については、23.2.1.p15 [containers.requirements.general] を参照してください。

于 2016-05-19T08:38:15.723 に答える