001 列表初始化
2020-01-15 本文已影响0人
赵者也
列表初始化
C++ 语言定义了初始化的好几种不同形式,这也是初始化问题复杂性的一个体现。例如,要想定义一个名为 units_sold 的 int 变量并初始化为 0,以下的 4 条语句都可以做到这一点:
int units_sold = 0;
int units_sold = {0};
int units_sold{0};
int units_sold(0);
作为 C++ 11 新标准的一部分,用花括号来初始化变量得到了全面应用,而在此之前,这种初始化的形式仅在某些受限的场合下才能使用。这种初始化的形式被称为列表初始化(list initialization)。现在,无论是初始化对象还是某些时候为对象赋新值,都可以使用这样一组由花括号括起来的初始值了。
当用于内置类型的变量时,这种初始化形式有一个重要特点:如果我们使用列表初始化且初始值存在丢失信息的风险,则编译器将报错:
long double ld = 3.1415926536;
int a{ld}, b={ld}; // 错误:转换未执行,因为存在丢失信息的危险
int c(ld), d=ld; // 正确:转换执行,且确实丢失了部分值
使用 long double 的值初始化 int 变量时可能丢失数据,所以编译器拒绝了 a 和 b 的初始化请求。其中,至少 ld 的小数部分会丢失掉,而且 int 也可能存不下 ld 的整数部分。
刚刚所介绍的看起来无关紧要,毕竟我们不会故意用 long double 的值去初始化 int 变量。
创建 pair 对象的函数
在新标准下,我们可以对返回值进行列表初始化:
std::pair<std::string, int> process(std::vector<std::string> &v) {
// 处理 v
if (!v.empty()) {
return {v.back(), v.back().size()}; // 列表初始化
} else {
return std::pair<std::string, int>(); // 隐式构造返回值
}
}
向 map 添加元素
对一个 map 进行 insert 操作时,必须记住元素类型是 pair。通常,对于想要插入的数据,并没有一个现成的 pair 对象。可以在 insert 的参数列表中创建一个 pair:
// 向 word_count 插入 word 的 4 种方法
word_count.insert({word, 1});
word_count.insert(make_pair(word, 1));
word_count.insert(pair<string, size_t>(word, 1));
word_count.insert(map<string, size_t>::value_type(word, 1));
如我们所见,在新标准下,创建一个 pair 最简单的方法是在参数列表中使用花括号初始化。也可以调用 make_pair 或显式构造 pair。最后一个 insert 调用中的参数:
map<string, size_t>::value_type(s, 1)
构造一个恰当的 pair 类型,并构造该类型的一个新对象,插入到 map 中。