列表初始化&&放置类型收窄
列表初始化 initializer_list
int arr[] = {1, 2, 3}; //C++98 和C++11都可以编译成功
std::map<string,int> = {{"11",1}, {"22",2}}; //C++98编译失败,C++11编译成功
std::vector<int> v = {1, 2}; //C++98编译失败,C++11编译成功
class UT
{
int i= 10; //C++98编译失败,C++11编译成功
}
- C++98对内置数组可以用花括号进行初始化,而对于vector数组、自定义类型无法通过花括号初始化。而在C++11中,这些都支持了,这是因为C++11支持了新特性。
- 使用头文件<initializer_list>中的类模板initializer_list< T >可以使得自定义的类使用初始化列表,容器map、vector等就是使用了此模板。
class UT
{
public:
UT(std::initializer_list<int> list)
{
for (auto iter = list.begin(); iter != list.end(); ++iter)
{
vecT.push_back(*iter);
}
}
void show() {
for (auto iter : vecT)
{
std::cout << iter << " ";
}
}
private:
std::vector<int> vecT;
};
int main() {
UT objUT{ 1, 2, 3, 4, 5 };
objUT.show();
return 0;
}
initializer_list的特性:
- 可以接受任意长度的初始化列表,但元素必须是同种类型;
- 提供了3个接口:size(),begin(),end()
- 防止类型收窄
类型收窄
类型收窄一般是指一些可以使得数据变化或精度丢失的隐式类型转换(新类型无法表示原有类型数据的值)如:
- 浮点类型隐式转化为整形数,如 int a = 2.2 ,实际a=2
- 高精度浮点数转为低精度浮点数,如double转float
- 整形(或非强类型的枚举)转为浮点型,若整数大到浮点数无法精确表示,视为类型收窄
- 整形(或非强类型的枚举)转为较低长度的整形,如 unsigned char = 1024,1024不能被8位的unsigned char所容纳,视为类型收窄
int iT1 = 2.0; //C++ 98 和C++11 都可以编译成功
int iT2 = {2.0}; //C++11 编译失败,因为类型收窄了
C++11中,初始化列表中的初始化的数据编译器会检查初始化的数据是否发生了类型收窄。
C++11中,列表初始化是唯一一种可以防止类型收窄的初始化方法