保留一个reference_wrapper个对象的vector,怎么可能?
Reserve a vector of reference_wrapper objects, how it is possible?
std::reference_wrapper
不是默认可构造的。所以我不能写任何:
std::vector<std::reference_wrapper<int>> vec(10);
std::array<std::reference_wrapper<int>, 3> arr;
然而,令我惊讶的是,您可以调用 std::reference_wrapper
个对象的向量的 std::vector::reserve
成员函数并有效地改变它的容量。
std::vector<std::reference_wrapper<int>> vec;
vec.reserve(10);
这怎么可能,因为 std::reference_wrapper
没有默认构造函数?
reserve
仅分配足够容纳 N
个单元的未初始化内存块,而不会在推送 N
个新元素时导致重新分配。
reserve
不构建任何新元素。最坏的情况只有 moves/copies 个已经创建。
可以参考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 不会创建新元素,但是 resize 会。
vector::reserve(N)
只是为 N
元素预分配存储容量。您正在使用的向量构造函数是 "default fill" 构造函数 - 它 创建 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
是 MoveInsertable
到 *this
.有问题的构造函数在 23.3.6.2.p3 [vector.cons] 中指定,并要求 T
应 DefaultInsertable
到 *this
.
reference_wrapper<>
是 MoveInsertable
但不是 DefaultInsertable
(正如您提到的,它不能默认构造)。这些概念的确切定义见23.2.1.p15 [containers.requirements.general].
std::reference_wrapper
不是默认可构造的。所以我不能写任何:
std::vector<std::reference_wrapper<int>> vec(10);
std::array<std::reference_wrapper<int>, 3> arr;
然而,令我惊讶的是,您可以调用 std::reference_wrapper
个对象的向量的 std::vector::reserve
成员函数并有效地改变它的容量。
std::vector<std::reference_wrapper<int>> vec;
vec.reserve(10);
这怎么可能,因为 std::reference_wrapper
没有默认构造函数?
reserve
仅分配足够容纳 N
个单元的未初始化内存块,而不会在推送 N
个新元素时导致重新分配。
reserve
不构建任何新元素。最坏的情况只有 moves/copies 个已经创建。
可以参考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 不会创建新元素,但是 resize 会。
vector::reserve(N)
只是为 N
元素预分配存储容量。您正在使用的向量构造函数是 "default fill" 构造函数 - 它 创建 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
是 MoveInsertable
到 *this
.有问题的构造函数在 23.3.6.2.p3 [vector.cons] 中指定,并要求 T
应 DefaultInsertable
到 *this
.
reference_wrapper<>
是 MoveInsertable
但不是 DefaultInsertable
(正如您提到的,它不能默认构造)。这些概念的确切定义见23.2.1.p15 [containers.requirements.general].