C++开发初级
1502 浏览 5 years, 11 months
3.1.7 初始化列表构造函数(仅限C++11)
版权声明: 转载请注明出处 http://www.codingsoho.com/初始化列表构造函数(仅限C++11)
初始化列表构造函数(Initializer-List Constructors
)是将std::initializer_list<T>
作为第一个参数的构造函数,并且没有任何其他参数(或者其他参数具有默认值)。在使用std::initializer_list<T>模板之前,必须包含<initializer_list>
头文件。下面的类演示了这种用法。
class PointSequence
{
public:
PointSequence(initializer_list<double> args)
{
if (args.size() % 2 != 0)
throw invalid_argument("initializer_list should contain even number of elements.");
for (auto iter = args.begin(); iter != args.end(); ++iter)
mVecPoints.push_back(*iter);
}
void dumpPoints() const
{
for (auto citer = mVecPoints.cbegin(); citer != mVecPoints.cend(); citer += 2) {
cout << "(" << *citer << ", " << *(citer+1) << ")" << endl;
}
}
protected:
vector<double> mVecPoints;
};
代码取自 InitializerListCtor\InitializerListCtor.cpp
在前面的示例中,初始化列表构造函数内部可以使用迭代器访问初始化列表的元素。迭代器将在后面讨论。可用sizes方法获取初始化列表中元素的数目。
可按照以下方式创建PointSequence对象:
PointSequence p1 = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
p1.dumpPoints();
try {
PointSequence p2 = {1.0, 2.0, 3.0};
} catch (const invalid_argument& e) {
cout << e.what() << endl;
}
代码取自 InitializerListCtor\InitializerListCtor.cpp
创建p2时会抛出一个异常,因为初始化列表中元素数目为奇数。前面的等号是可选的,可以忽略,例如:
PointSequence p1 = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
C++ 11 STL完全支持初始化列表构造函数。例如,可使用初始化列表初始化std::vector容器。
std::vector<std::string> myVec = {"String 1", "String 2", "String 3"};
如果您使用的编译器不支持C++11标准,可以调用一些push_back()来初始化向量:
std::vector<std::string> myVec;
myVec.push_back("String 1");
myVec.push_back("String 2");
myVec.push_back("String 3");
初始化列表构造函数对于C++11的统一初始化(uniform initialization)
功能非常重要,这一功能将在后面讲述。
初始化列表并不限于构造函数,还可以用于普通函数,后面将讲述这一内容。
上面我们用到的C++的新特性auto
,简单介绍一下
auto
C++11引入auto关键词,推测类型
auto i=42; //推测类型为int
double f();
auto d=f(); //根据f的返回值推测d为double
vector<string> v;
auto it=v.begin(); //推测类型为vector<string>::iterator
不能用auto定义未分配变量,下面是错误的
auto i;
在可以推测数据类型的环境下,使用auto代替数据 类型,由编译器确定具体的类型。
基于范围的for循环
C++11为基于迭代器区间的容器或数组等构建提供新的for循环
for( elem : coll ) { … }
凡是支持foreach的操作,都可以使用for替代
int a[]={1,3,2,5,6};
for( int i : a){
cout<<i<<endl;
}
上面for循环遍历数组中元素,但不能修改元素。
for(auto& elem : a){
elem*=2;
}
通过引用,可以修改数组元素。
for的另一个示例
vector<int v;
v.push_back(3);
// …
int sum=0;
for(const auto& elem : v)
sum+=elem;
for的等价形式
for( elem : coll ) { … }
// Equal to below
auto it=coll.begin();
for(; it!=coll.end(); ++it)
{
const auto& elem = *it;
…
}