跳到主要内容

std::vector 构造函数

std::vector 类可以通过多种不同的方式构造。使用右上角的按钮,方便地使用箭头导航。

注意

std::vector 是一个 类模板,具有以下类型参数,这些参数在构造函数中使用

公共T元素类型
公共分配器分配器 类型,用于分配内部存储

默认构造函数

// 1)
vector()
: vector( Allocator() )
{
}

// 2)
explicit vector( Allocator const& alloc );
  • 如果 Allocator 的构造函数也是 noexcept,则构造函数 1) 是 noexcept
  • 构造函数 2) 是 noexcept,因为 Allocator 之前已构造
  • 两个构造函数都是 constexpr

默认构造函数。构造一个空容器。如果未提供分配器,则从默认构造的实例中获取分配器。

复杂度

常数。

示例

#include <iostream>
#include <vector>

int main() {
// Default constructed vector<int>:
std::vector<int> v;

std::cout << "v.size(): " << v.size();
}
结果
v.size(): 0

重复值构造函数

// prism-push-types:size_type
constexpr vector(
size_type count,
T const& value,
Allocator const& alloc = Allocator()
);

使用 valuecount 份副本构造向量。

复杂度

count 成线性关系。

示例

#include <iostream>
#include <vector>

int main() {
std::vector<int> v(4, 15);

for (auto elem : v)
std::cout << elem << ' ';
}
结果(控制台)
15 15 15 15 

count 默认元素构造函数

// prism-push-types:size_type
constexpr explicit vector(
size_type count,
Allocator const& alloc = Allocator()
);

使用 count 个默认插入的 T 类型元素构造向量。不进行复制。

复杂度

count 成线性关系。

示例

#include <iostream>
#include <vector>

int main() {

// |0,0,0,0|
auto vec = std::vector<int>(4);
// |0,0,0,0,13|
vec.push_back(13);

for (auto elem : vec)
std::cout << elem << ' ';
}
结果(控制台)
0 0 0 0 13

基于范围的构造函数

template <typename InputIt>
constexpr vector(
InputIt first,
InputIt last,
Allocator const& alloc = Allocator()
);

使用范围 [first, last) 的内容构造容器。

重载决议
此重载仅在 InputIt 满足 LegacyInputIterator 时才参与重载解析,以避免与重复值重载的歧义

复杂度

给定 firstlast 之间的距离为 N

  • 如果 firstlast 都是 前向、双向或随机访问迭代器,则 T 的复制构造函数仅被调用 N 次,并且不会发生重新分配。
  • 否则(firstlast 只是 输入迭代器),T 的复制构造函数被调用 O(N) 次,并且重新分配发生 O(log N) 次。

示例

#include <iostream>
#include <vector>

int main() {
char buf[] = "Hello, World";
auto vec = std::vector<char>(
std::begin(buf),
std::next(std::begin(buf), 5)
);

for (auto elem : vec)
std::cout << elem << ' ';
}
结果(控制台)
H e l l o

复制构造函数

// (1)
constexpr vector( vector const& other );

// (2)
constexpr vector(
vector const& other,
Allocator const& alloc
);

复制构造函数。使用 other 内容的副本构造容器。第二个版本使用 alloc 作为分配器。

获取分配器和推导

分配器通过调用如下方式获得

std::allocator_traits<allocator_type>::select_on_container_copy_construction(other.get_allocator())

复杂度

other 的大小呈线性关系。

示例

#include <iostream>
#include <vector>

int main() {
// ⚠ using C++17 CTAD
auto vec = std::vector{5, 21, 37, 11};
auto copied = std::vector(vec);

copied[2] = 38;

for (auto elem: vec) std::cout << elem << ' ';

std::cout << '\n';

for (auto elem: copied) std::cout << elem << ' ';
}
结果(控制台)
5 21 37 11
5 21 38 11

移动构造函数

// 1)
constexpr vector( vector&& other ) noexcept;

// 2)
constexpr vector(
vector&& other,
Allocator const& alloc
);

移动构造函数。使用移动语义构造具有 other 内容的容器。分配器通过从属于 other 的分配器进行移动构造获得。移动后,other 保证是empty()

第二个重载接受一个用于构造容器的分配器,从 other 移动内容。如果 alloc != other.get_allocator(),这将导致逐元素移动(在这种情况下,移动后 other 不保证是 empty())。

分配器推导

模板参数 Allocator 仅在使用类模板参数推导时从第一个参数推导

.

 (自 C++23 起)

复杂度

如果 alloc != other.get_allocator() 则呈线性关系,否则为常数。

示例

#include <iostream>
#include <vector>
#include <iomanip>

int main() {

auto prev = std::vector{15, 3, 8};

auto current = std::vector( std::move(prev) );

std::cout << "prev.empty(): " << std::boolalpha << prev.empty() << '\n';
std::cout << "current: ";
for (auto elem: current)
std::cout << elem << ' ';
}
结果(控制台)
prev.empty(): true
15 3 8

初始化列表构造函数

constexpr vector(
std::initializer_list<T> init,
Allocator const& alloc = Allocator()
);

使用初始化列表 init 的内容构造容器。

注意

此重载的存在意味着列表初始化和直接初始化做不同的事情

std::vector<int> b{3}; // creates a 1-element vector holding {3}
std::vector<int> a(3); // creates a 3-element vector holding {0, 0, 0}

std::vector<int> d{1, 2}; // creates a 2-element vector holding {1, 2}
std::vector<int> c(1, 2); // creates a 1-element vector holding {2}

复杂度

init 的大小呈线性关系。

示例

#include <iostream>
#include <vector>

int main() {
std::vector<int> v = { 14, 30, 18 };

for (auto elem : v)
std::cout << elem << ' ';
}
结果(控制台)
14 30 18
本文源自此 CppReference 页面。它可能为了改进或编辑偏好而被修改。点击“编辑此页面”查看此文档的所有更改。
悬停查看原始许可证。

std::vector 构造函数

std::vector 类可以通过多种不同的方式构造。使用右上角的按钮,方便地使用箭头导航。

注意

std::vector 是一个 类模板,具有以下类型参数,这些参数在构造函数中使用

公共T元素类型
公共分配器分配器 类型,用于分配内部存储

默认构造函数

// 1)
vector()
: vector( Allocator() )
{
}

// 2)
explicit vector( Allocator const& alloc );
  • 如果 Allocator 的构造函数也是 noexcept,则构造函数 1) 是 noexcept
  • 构造函数 2) 是 noexcept,因为 Allocator 之前已构造
  • 两个构造函数都是 constexpr

默认构造函数。构造一个空容器。如果未提供分配器,则从默认构造的实例中获取分配器。

复杂度

常数。

示例

#include <iostream>
#include <vector>

int main() {
// Default constructed vector<int>:
std::vector<int> v;

std::cout << "v.size(): " << v.size();
}
结果
v.size(): 0

重复值构造函数

// prism-push-types:size_type
constexpr vector(
size_type count,
T const& value,
Allocator const& alloc = Allocator()
);

使用 valuecount 份副本构造向量。

复杂度

count 成线性关系。

示例

#include <iostream>
#include <vector>

int main() {
std::vector<int> v(4, 15);

for (auto elem : v)
std::cout << elem << ' ';
}
结果(控制台)
15 15 15 15 

count 默认元素构造函数

// prism-push-types:size_type
constexpr explicit vector(
size_type count,
Allocator const& alloc = Allocator()
);

使用 count 个默认插入的 T 类型元素构造向量。不进行复制。

复杂度

count 成线性关系。

示例

#include <iostream>
#include <vector>

int main() {

// |0,0,0,0|
auto vec = std::vector<int>(4);
// |0,0,0,0,13|
vec.push_back(13);

for (auto elem : vec)
std::cout << elem << ' ';
}
结果(控制台)
0 0 0 0 13

基于范围的构造函数

template <typename InputIt>
constexpr vector(
InputIt first,
InputIt last,
Allocator const& alloc = Allocator()
);

使用范围 [first, last) 的内容构造容器。

重载决议
此重载仅在 InputIt 满足 LegacyInputIterator 时才参与重载解析,以避免与重复值重载的歧义

复杂度

给定 firstlast 之间的距离为 N

  • 如果 firstlast 都是 前向、双向或随机访问迭代器,则 T 的复制构造函数仅被调用 N 次,并且不会发生重新分配。
  • 否则(firstlast 只是 输入迭代器),T 的复制构造函数被调用 O(N) 次,并且重新分配发生 O(log N) 次。

示例

#include <iostream>
#include <vector>

int main() {
char buf[] = "Hello, World";
auto vec = std::vector<char>(
std::begin(buf),
std::next(std::begin(buf), 5)
);

for (auto elem : vec)
std::cout << elem << ' ';
}
结果(控制台)
H e l l o

复制构造函数

// (1)
constexpr vector( vector const& other );

// (2)
constexpr vector(
vector const& other,
Allocator const& alloc
);

复制构造函数。使用 other 内容的副本构造容器。第二个版本使用 alloc 作为分配器。

获取分配器和推导

分配器通过调用如下方式获得

std::allocator_traits<allocator_type>::select_on_container_copy_construction(other.get_allocator())

复杂度

other 的大小呈线性关系。

示例

#include <iostream>
#include <vector>

int main() {
// ⚠ using C++17 CTAD
auto vec = std::vector{5, 21, 37, 11};
auto copied = std::vector(vec);

copied[2] = 38;

for (auto elem: vec) std::cout << elem << ' ';

std::cout << '\n';

for (auto elem: copied) std::cout << elem << ' ';
}
结果(控制台)
5 21 37 11
5 21 38 11

移动构造函数

// 1)
constexpr vector( vector&& other ) noexcept;

// 2)
constexpr vector(
vector&& other,
Allocator const& alloc
);

移动构造函数。使用移动语义构造具有 other 内容的容器。分配器通过从属于 other 的分配器进行移动构造获得。移动后,other 保证是empty()

第二个重载接受一个用于构造容器的分配器,从 other 移动内容。如果 alloc != other.get_allocator(),这将导致逐元素移动(在这种情况下,移动后 other 不保证是 empty())。

分配器推导

模板参数 Allocator 仅在使用类模板参数推导时从第一个参数推导

.

 (自 C++23 起)

复杂度

如果 alloc != other.get_allocator() 则呈线性关系,否则为常数。

示例

#include <iostream>
#include <vector>
#include <iomanip>

int main() {

auto prev = std::vector{15, 3, 8};

auto current = std::vector( std::move(prev) );

std::cout << "prev.empty(): " << std::boolalpha << prev.empty() << '\n';
std::cout << "current: ";
for (auto elem: current)
std::cout << elem << ' ';
}
结果(控制台)
prev.empty(): true
15 3 8

初始化列表构造函数

constexpr vector(
std::initializer_list<T> init,
Allocator const& alloc = Allocator()
);

使用初始化列表 init 的内容构造容器。

注意

此重载的存在意味着列表初始化和直接初始化做不同的事情

std::vector<int> b{3}; // creates a 1-element vector holding {3}
std::vector<int> a(3); // creates a 3-element vector holding {0, 0, 0}

std::vector<int> d{1, 2}; // creates a 2-element vector holding {1, 2}
std::vector<int> c(1, 2); // creates a 1-element vector holding {2}

复杂度

init 的大小呈线性关系。

示例

#include <iostream>
#include <vector>

int main() {
std::vector<int> v = { 14, 30, 18 };

for (auto elem : v)
std::cout << elem << ' ';
}
结果(控制台)
14 30 18
本文源自此 CppReference 页面。它可能为了改进或编辑偏好而被修改。点击“编辑此页面”查看此文档的所有更改。
悬停查看原始许可证。