一:initializer_list的使用
我们能够通过initializer_list类提供的size(),begin(),end()函数来访问initializer_list类对象的成员。如下面例子代码所示:
void f(initializer_list<int> arg)
{
for(int i=0;i!=arg.size();++i)
cout<<args.begin()[i]<<"\n";//注意不是args[i],因为initializer_list不提供下标操作;
}
or
void f(initializer_list<int> arg)
{
for(auto p=arg.begin();p!=arg.end();++p)
cout<<*p<<"\n";
}
or
void f(initializer_list<int> arg)
{
for(auto x:arg)
cout<<x<<"\n";
}
需要注意的是,initializer_list类对象中的元素是不能够被更改的。比如下面的代码就是错误的
{
void f(initializer_list<int> x,int val)
{
*x.begin()=val; //error,immutable
return *x.begin(); //okay!
}
二:类中的deleted函数
在类中,我们能够声明一个成员函数不存在,这样如果使用了这个成员函数,就会出现编译错误。
1:我们经常用这种方法在类层次的基类中删除其复制函数和移动函数(在这种情况下,派生类中没有合成的复制函数和移动函数),例子如下:
class Base{
public:
Base& operator=(const Base&)=delete;
Base(const Base&)=delete;
Base& operator=(Base&&)=delete;
Base(Base&&)=delete;
};
Base x1;
Base x2(x1); //error! no copy constructor;
2:事实上我们不仅能够删除复制和移动函数,我们可以删除任何成员函数。比如我们能够通过删除成员函数来控制一个类在哪里能够被分配,代码如下:
class not_on_stack{
//...
~not_on_stack()=delete; //不能调用析构函数;
}
class not_on_free_store{
//...
void* operator new(size_t)=delete; //不能使用new操作符;
};
由于not_on_stack类不能调用析构函数,因此不能够定义它的局部变量,但not_on_free_stack类的析构函数没有被”deleted”,因此能够定义它的局部变量,正如如下显示的:
void f()
{
not_on_stack v1; // error: can't destroy!
not_on_free_store v2; //Okay;
}
由于not_on_free_store类的new操作符被禁止使用了,因此我们不能再自由内存中定义一个该类的对象;not_on_stack类的new操作符没有被”deleted”,因此能够在自由内存中定义一个not_on_stack类的对象,正如如下显示的:
void f()
{
not_on_stack* p1=new not_on_stack; //okay;
not_on_free_store* p2=new not_on_free_store ;//error; can't allocate
}
要注意到=delete函数和未被声明的函数之间的不同,对于前者,编译器知道一个deleted函数正在被使用,因此给出错误。对于后者来说,虽然这个函数未被声明,但编译器会去尽力寻找替代的函数,比如如果析构函数未被声明,编译器会自动产生一个默认析构函数,如果类中operator new()未被声明,编译器会使用全局域中定义的operator new()函数。