为什么 std::vector 有 2 个构造函数而不是 1 个带默认参数的构造函数?

问题描述 投票:0回答:3

我查看了cppreference.com并发现了这个

vector();
explicit vector( const Allocator& alloc );

为什么不只是

explicit vector(const Allocator& alloc = Allocator());

1 个构造函数而不是 2 个。 是否有一个原因?与

resize(std::size_t,const T& t)
和相同
resize(std::size_t)
为什么不只是
resize(std::size_t,const T& t = T())

c++ c++11 stl std stdvector
3个回答
4
投票

如果默认构造函数是显式的,因为它只是带有默认值的单参数版本,所以无法使用

{}
初始化向量。 对于
resize
,它要求元素类型是可复制,而不仅仅是值初始化(技术上是值插入)新元素。


1
投票

关于 std::vector:
对于第一个问题,这是一个效用和效率的问题。
对于不带参数的向量():

vector();

分配器对象由模板提供,默认为std::allocator。

定义可以写成:

constexpr vector() : elem(nullptr), array_size(0), space(0) {}

对于带有作为参数提供的分配器对象的向量:

constexpr explicit vector(const Allocator& alloc) noexcept;

定义可以写成:

constexpr explicit vector(const Allocator& alloc) noexcept : elem(nullptr), array_size(0), space(0), v_alloc(alloc) {}

两者都会构造一个空向量。 如果“Allocator”是自定义分配器,即“my_allocator”,则通过参数分配对象,允许具有与模板提供的分配器对象不同的特征。 当分配器对象由模板提供时,对象内的所有值都有默认值。 当分配器对象作为参数提供时,可以在将该对象作为参数传递之前重新配置分配器。

当不带参数构造向量时,会默认构造分配器。 当使用参数构造向量时,首先默认构造分配器,然后从参数复制分配。 因此,使用一个参数默认为“(const Allocator& alloc = Allocator())”的构造函数效率会较低。

对于第二个问题,这是一个效率问题。

“void resize(std::size_t count)”在向量大小调整得更大时附加默认元素。 每个附加元素默认是通过 std::allocator_traits:

构造的
std::allocator_traits<decltype(v_alloc)>::construct(v_alloc, ptr);

当向量大小调整得更大时,“void resize(std::size_t count, const T& value)”会使用复制构造函数附加元素“value”。

std::allocator_traits<decltype(v_alloc)>::construct(v_alloc, ptr, value)

如果提供“T()”作为“value”的默认值,则附加元素是复制构造的,而不是默认构造的。


1
投票

explicit vector(const Allocator& alloc = Allocator());
需要
Allocator
既可默认构造又可复制构造。 如果
Allocator
无法执行其中一项操作,那么您将无法默认构造
vector

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.