C++2.0—— 一致性初始化(uniform initialization) 与 Initializer_list

一致性初始化(uniform initialization)

C++11引入了“一致性初始化”概念,意思是面对任何初始化动作,可使用相同语法 { },进行一致性的初始化。

原理解析:当编译器看到大括号包起来的东西时,会生成一个initializer_list<T>(initializer_list它其实是关联一个array<T,n>),然后再调用构造函数时,一个个从array分解取出来然后调用构造函数,但是如果这个函数自身提供了initializer_list<T>参数类型的构造函数时,则不会分解而是直接传过去。

	int i;//未初始化,如果直接使用会报错,error C4700: 使用了未初始化的局部变量“i”
	int j{};
	i = 0;
	cout << "i=" << i << "j=" << j << endl;	

	int k(3.4);		// warning C4244: “初始化”: 从“double”转换到“int”,可能丢失数据
	//int m{ 3.4 };	//error C2397: 从“double”转换到“int”需要收缩转换,不允许窄化数据处理
	cout << "k=" << k << endl;

	int value[]{1,2,3,4,5,6,7,8,9};
	cout << "sizeof(value)= " << sizeof(value) << endl;
	int value2[] = { 1,2,3,4,5,6,7,8,9 };
	cout << "sizeof(value2)= " << sizeof(value2) << endl;

	vector<int> v1{ 1, 2, 3 };

std::initializer_list

定义于头文件 <initializer_list>

  

template< class T >
class initializer_list;

 (C++11 起)
   

std::initializer_list<T> 类型对象是一个访问 const T 类型对象数组的轻量代理对象。
std::initializer_list 对象在这些时候自动构造:

  • 花括号初始化器列表列表初始化一个对象,其中对应构造函数接受一个 std::initializer_list 参数
  • 花括号初始化器列表赋值的右运算数,或函数调用参数,而对应的赋值运算符/函数接受 std::initializer_list 参数
  • 绑定花括号初始化器列表到 auto ,包括在范围 for 循环

initializer_list 可由一对指针或指针与其长度实现。复制一个 std::initializer_list 不会复制其底层对象。

底层数组不保证在原始 initializer_list 对象的生存期结束后继续存在。 std::initializer_list 的存储是未指定的(即它可以是自动、临时或静态只读内存,依赖场合)。(C++14 前)
底层数组是 const T[N] 类型的临时数组,其中每个元素都从原始初始化器列表的对应元素复制初始化(除非窄化转换非法)。底层数组的生存期与任何其他临时对象相同,除了从数组初始化 initializer_list 对象会延长数组的生存期,恰如绑定引用到临时量(有例外,例如对于初始化非静态类成员)。底层数组可以分配在只读内存。(C++14 起)

若声明了 std::initializer_list 的显式或偏特化则程序为谬构。

(C++17 起)

整个测试程序如下:

#include <iostream>
#include <vector>
#include <initializer_list>
using namespace std;

template <class T>
struct S {
	std::vector<T> v;

	S(std::initializer_list<T> l) : v(l) {
		std::cout << "constructed with a " << l.size() << "-element list\n";
	}
	void append(std::initializer_list<T> l) {
		v.insert(v.end(), l.begin(), l.end());
	}
	std::pair<const T*, std::size_t> c_arr() const {
		return{ &v[0], v.size() };  // 在 return 语句中复制列表初始化				
	}
};

/*
* initializer_list 
*/

template <typename T>
void print(initializer_list<T> list)
{
	for (auto p = list.begin(); p != list.end(); ++p)
	{
		cout << *p << endl;
	}
}


/*
* 一致性初始化(uniform initialization)
* 实现思想:
*	当编译器看到大括号包起来的东西时,会生成一个initializer_list<T>(initializer_list它其实是关联一个array<T,n>),
*	然后再调用构造函数时,一个个从array分解取出来然后调用构造函数,但是如果这个函数自身提供了initializer_list<T>
*	参数类型的构造函数时,则不会分解而是直接传过去。
*/

int main() 
{
	int i;//未初始化,如果直接使用会报错,error C4700: 使用了未初始化的局部变量“i”
	int j{};
	i = 0;
	cout << "i=" << i << "j=" << j << endl;	

	int k(3.4);		// warning C4244: “初始化”: 从“double”转换到“int”,可能丢失数据
	//int m{ 3.4 };	//error C2397: 从“double”转换到“int”需要收缩转换,不允许窄化数据处理
	cout << "k=" << k << endl;

	int value[]{1,2,3,4,5,6,7,8,9};
	cout << "sizeof(value)= " << sizeof(value) << endl;
	int value2[] = { 1,2,3,4,5,6,7,8,9 };
	cout << "sizeof(value2)= " << sizeof(value2) << endl;

	vector<int> v1{ 1, 2, 3 };

	S<int> s = { 1, 2, 3, 4, 5 }; // 复制初始化
	s.append({ 6, 7, 8 });      // 函数调用中的列表初始化

	std::cout << "The vector size is now " << s.c_arr().second << " ints:\n";

	
	print({ 1,2,3,4,5,6,7,8,9 });

	return 0;
}



输出结果:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值