C++11之正则表达式(regex_match、regex_search、regex_replace)
C++11之线程库(Thread、Mutex、atomic、lock_guard、同步)
C++11之智能指针(unique_ptr、shared_ptr、weak_ptr、auto_ptr)浅谈内存管理
C++11之强制类型转换(static_cast,const_cast,dynamic_cast,reinterpret_cast)
C++11之Lanbda表达式(匿名函数)
C++11之右值引用:移动语义和完美转发(带你了解移动构造函数、纯右值、将亡值、右值引用、std::move、forward等新概念)
C++11之继承构造函数(using 声明)
C++11之委派构造函数
C++11之显式转换操作符-explicit
其实在初始化列表这个词并不陌生,早在C++98中就已经引入了。可以通过{}一对大括号对数组元素进行统一的初始值设定。
如:int a{2}; int arr[] = {1,5,2};
但是这种方式初始化仅仅支持内置类型,也就是说结构体类型,容器都是不支持的。
在C++11标准中,又对初始化列表的功能进行一次强化。
初始化列表前有无=
等号作用相同,例如下面几种写法都是正确的。
1 int a = {5 + 5};
2 int a{2+1};
3 int a{3+1};
4 int* p = new int(1);
5 int* p = new int{9};
initializer_list
是C++11提供的新类型,定义在头文件中。用于表示某种特定类型的值的数组,和vector
一样,initializer_list是一种模板类型。
#include
#include
#include
using namespace std;
class A
{
public:
A(int a, int b){}
};
enum class Gender
{
boy = 1,
girl = 2,
};
class People
{
public:
People(initializer_list<pair<string, Gender>> l)
{
initializer_list<pair<string, Gender>>::const_iterator iter = l.begin();
for(; iter != l.end(); ++iter)
{
data.push_back(*iter);
}
}
private:
vector<pair<string, Gender>> data;
};
int main()
{
People pp = { {"aa", Gender::boy}, {"bb", Gender::girl} };
return 0;
}
在上面的代码中,为这个类提供了一个initializer_list
模板版本的构造函数。这样就可以采用通过初始化列表的方式进行初始化了。
initializer_list
除了可以初始化还可以作为函数的参数列表,就可以让函数支持初始化列表。
#include
#include
#include
using namespace std;
void test(initializer_list<int> iv){}
int main()
{
test({ 1,5,3,99 });
test({ 1 });
return 0;
}
在上面这个例子中,定义了一个接受初始化列表的函数test
。这种方法不局限于全局函数,成员函数也是可以的。
initializer_list
还可以用在重载下标运算符中operator[]
。
下面这个例子稍微复杂一点,但正因为复杂也能体现出初始化列表的便捷性。
创建了一个类A
,其中重载了下标运算符,赋值运算符。实现了一个可以通过下标运算符[]
来对数组内的值进行批量初始化。
#include
#include
#include
using namespace std;
class A
{
public:
/*
* 用于记录需要初始化的下表
*/
A& operator[](initializer_list<int> l)
{
for(initializer_list<int>::const_iterator iter = l.begin(); iter != l.end(); ++iter)
{
index.push_back(*iter);
}
return *this;
}
/*
* 用于将之前index提前保存好的下表进行统一初始化
*/
A& operator=(int v)
{
if(false == index.empty())
{
for (vector<int>::const_iterator iter = index.begin(); iter != index.end(); ++iter)
{
if (d.size() < *iter)
{
d.resize(*iter);
}
d.at(*iter - 1) = v;
}
index.clear();
return *this;
}
}
void Print()
{
for(const auto elem : d)
{
cout << elem << " ";
}
cout << endl;
}
private:
vector<int> index; // 辅助数组,用于记录index
vector<int> d;
};
int main()
{
A a;
a[{1, 5, 8, 4}] = 1;
a.Print();
a[{2, 1, 6, 9, 4}] = 6;
a.Print();
return 0;
}
可以看到我们自定义批量初始化仅需要一行即可完成a[{1, 5, 8, 4}] = 1;
。可见初始化的灵活性、强大性。