您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# C++11中初始化列表initializer lists怎么用
## 目录
1. [初始化列表概述](#初始化列表概述)
2. [基本语法与使用场景](#基本语法与使用场景)
3. [标准容器中的初始化列表](#标准容器中的初始化列表)
4. [自定义类型支持初始化列表](#自定义类型支持初始化列表)
5. [初始化列表与构造函数重载](#初始化列表与构造函数重载)
6. [性能分析与注意事项](#性能分析与注意事项)
7. [与其他初始化方式的对比](#与其他初始化方式的对比)
8. [高级应用场景](#高级应用场景)
9. [常见问题与解决方案](#常见问题与解决方案)
10. [总结与最佳实践](#总结与最佳实践)
---
## 初始化列表概述
C++11引入的初始化列表(initializer lists)是语言核心的重大改进之一,它提供了一种统一、简洁的初始化方式,彻底改变了C++中对象初始化的语法规则。
### 历史背景
在C++11之前,初始化语法存在多种不一致的情况:
```cpp
int arr[] = {1, 2, 3}; // C风格数组初始化
std::vector<int> vec; // 需要后续push_back
struct Point { int x,y; };
Point p = {1, 2}; // 聚合初始化
初始化列表基于std::initializer_list
模板类实现,它是一个轻量级的代理容器,提供对常量元素序列的访问。关键特性包括:
- 编译期构造,无运行时开销
- 元素类型必须一致
- 元素是只读的(const)
初始化列表的引入促成了”列表初始化”(list initialization)语法:
// 以下三种形式等效
std::vector<int> v1 = {1, 2, 3}; // 拷贝列表初始化
std::vector<int> v2{1, 2, 3}; // 直接列表初始化
std::vector<int> v3({1, 2, 3}); // 显式构造函数调用
初始化列表可以用于多种上下文环境:
int a{5}; // 基本类型
int b[] = {1, 2, 3}; // 数组
std::string s{"Hello"}; // 类类型
void func(std::initializer_list<int> list) {
for (auto i : list) std::cout << i << " ";
}
func({1, 2, 3}); // 输出: 1 2 3
std::vector<int> createVector() {
return {1, 2, 3}; // 避免显式临时对象
}
与auto
关键字结合使用时需注意:
auto x = {1, 2, 3}; // x的类型是std::initializer_list<int>
auto y{1, 2, 3}; // C++17前错误,C++17后同上
auto z{42}; // C++17前为initializer_list,C++17后为int
std::vector<int> empty{}; // 明确调用默认构造函数
std::vector<int> empty2; // 同上
int x{5.0}; // 错误: 从double到int的窄化转换
char c{999}; // 错误: 超出char范围的窄化转换
C++标准库全面支持初始化列表,极大简化了容器使用。
// vector
std::vector<std::string> cities = {"Berlin", "London", "Tokyo"};
// deque
std::deque<int> dq{1, 2, 3, 4};
// list
std::list<double> ld{1.1, 2.2, 3.3};
// set
std::set<int> primes{2, 3, 5, 7, 11};
// map的几种初始化方式
std::map<std::string, int> m1 = {
{"Alice", 25},
{"Bob", 30}
};
// 嵌套初始化列表
std::map<std::string, std::vector<int>> scores{
{"Alice", {90, 85, 95}},
{"Bob", {80, 75, 70}}
};
// array(注意列表大小必须匹配)
std::array<int, 3> arr{1, 2, 3};
// pair和tuple
std::pair<int, std::string> p{1, "one"};
std::tuple<int, double, char> t{1, 2.0, 'a'};
要使自定义类型支持初始化列表,需要提供接受std::initializer_list
的构造函数:
class MyVector {
std::vector<int> data;
public:
MyVector(std::initializer_list<int> init)
: data(init) {}
void append(std::initializer_list<int> values) {
data.insert(data.end(), values.begin(), values.end());
}
};
// 使用示例
MyVector mv{1, 2, 3};
mv.append({4, 5, 6});
class Confusing {
public:
Confusing(int, int); // (1)
Confusing(std::initializer_list<int>); // (2)
};
Confusing c1(1, 2); // 调用(1)
Confusing c2{1, 2}; // 调用(2)
Confusing c3(1, 2.0); // 调用(1)
Confusing c4{1, 2.0}; // 错误: 窄化转换
class Circle {
double radius;
std::string color;
public:
Circle(double r) : radius(r), color("black") {}
Circle(std::initializer_list<double> init)
: Circle(init.size() ? *init.begin() : 0.0) {}
};
(因篇幅限制,以下为各章节简要提纲,实际文章需扩展至10050字)
explicit
关键字的影响// 综合示例:矩阵类初始化
class Matrix {
std::vector<std::vector<double>> data;
public:
Matrix(std::initializer_list<std::initializer_list<double>> rows) {
for (auto& row : rows) {
data.emplace_back(row);
}
}
};
Matrix m{
{1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0}
};
初始化列表作为C++11最重要的特性之一,不仅简化了代码编写,更提供了一种类型安全的初始化机制。合理运用可以显著提高代码质量和开发效率,但也需要注意避免过度使用导致的构造函数重载歧义等问题。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。