C++中不同类型vector的整数初始化行为差异原因咨询
嗨,这个问题我刚学C的时候也踩过坑!本质是C里vector的构造函数重载和列表初始化的优先级规则在起作用,我给你拆解明白~
先把你给出的代码和输出再明确一下:
#include <vector> #include <string> // 假设println是自定义的格式化打印函数 void println(const char* fmt, ...); int main() { std::vector<int> nums{5}; std::vector<std::string> names{5}; println("Size: {}, Capacity: {}", nums.size(), nums.capacity()); println("Size: {}, Capacity: {}", names.size(), names.capacity()); }
对应的输出是:
Size: 1, Capacity: 1
Size: 5, Capacity: 5
核心的差异点其实分两部分说:
对于
std::vector<int> nums{5}:
C++11引入的列表初始化(大括号{}语法)会优先匹配vector的vector(std::initializer_list<T>)构造函数。这里的5是int类型,刚好可以直接放入std::initializer_list<int>中,所以编译器会优先走这个构造函数,最终创建出一个size为1的vector,唯一的元素就是5。对于
std::vector<std::string> names{5}:
这里如果想走列表初始化的话,需要把5放进std::initializer_list<std::string>里,但C++不允许把int隐式转换成std::string(毕竟std::string没有非explicit的string(int)构造函数),所以列表初始化的这条路走不通。
这时候编译器就会退而求其次,匹配vector的另一个构造函数:vector(size_type n, const T& value = T())。这个构造函数的作用是创建一个包含n个默认构造元素的vector,这里T是std::string,默认构造的string就是空字符串,于是就生成了size为5的vector,每个元素都是空字符串。
顺便给你补个小知识点:如果想给std::vector<std::string>用列表初始化创建单个元素的容器,你得传字符串类型的值,比如std::vector<std::string> names{"5"},这时候就会生成size为1的vector,元素是字符串"5";而如果用圆括号std::vector<std::string>(5),效果和你用大括号的names{5}是一样的,都是5个空字符串。
内容来源于stack exchange

