在Linux下编译C++11
#include<typeinfo>
int main()
{
auto a=10;
cout<<typeid(a).name()<<endl; //得到a的类型,只是一个字符串
return 0;
}编译需要加-std=c++11,如下例:
auto
C++11中引入auto第一种作用是为了自动类型推导
auto的自动类型推导,用于从初始化表达式中推断出变量的数据类型。通过auto的自动类型推导,可以大大简化我们的编程工作
auto实际上实在编译时对变量进行了类型推导,所以不会对程序的运行效率造成不良影响
另外,似乎auto并不会影响编译速度,因为编译时本来也要右侧推导然后判断与左侧是否匹配。
auto a; // 错误,auto是通过初始化表达式进行类型推导,如果没有初始化表达式,就无法确定a的类型 auto i = 1; auto d = 1.0; auto str = "Hello World"; auto ch = 'A'; auto func = less<int>(); vector<int> iv; auto ite = iv.begin(); auto p = new foo() // 对自定义类型进行类型推导
auto不光有以上的应用,它在模板中也是大显身手,比如下例这个加工产品的例子中,如果不使用auto就必须声明Product这一模板参数:
template <typename Product, typename Creator>
void processProduct(const Creator& creator) {
Product* val = creator.makeObject();
// do somthing with val
}template <typename Creator>
void processProduct(const Creator& creator) {
auto val = creator.makeObject();
// do somthing with val
}抛弃了麻烦的模板参数,整个代码变得更加正解了。
decltype
decltype实际上有点像auto的反函数,auto可以让你声明一个变量,而decltype则可以从一个变量或表达式中得到类型,有实例如下:
int x = 3; decltype(x) y = x;
template <typename Creator>
auto processProduct(const Creator& creator) -> decltype(creator.makeObject()) {
auto val = creator.makeObject();
// do somthing with val
}typeid().name()与decltype
typeid().name得到的仅仅是一个字符串
而decltype可以提取出类型
nullptr
nullptr是为了解决原来C++中NULL的二义性问题而引进的一种新的类型,因为NULL实际上代表的是0
void F(int a){
cout<<a<<endl;
}
void F(int *p){
assert(p != NULL);
cout<< p <<endl;
}
int main(){
int *p = nullptr;
int *q = NULL;
bool equal = ( p == q ); // equal的值为true,说明p和q都是空指针
int a = nullptr; // 编译失败,nullptr不能转型为int
F(0); // 在C++98中编译失败,有二义性;在C++11中调用F(int)
F(nullptr);
return 0;
}序列for循环
在C++中for循环可以使用类似java的简化的for循环,可以用于遍历数组,容器,string以及由begin和end函数定义的序列(即有Iterator),示例代码如下:
map<string, int> m{{"a", 1}, {"b", 2}, {"c", 3}};
for (auto p : m){
cout<<p.first<<" : "<<p.second<<endl;
}更加优雅的初始化
在引入C++11之前,只有数组能使用初始化列表,其他容器想要使用初始化列表,只能用以下方法:
int arr[3] = {1, 2, 3};
vector<int> v(arr, arr + 3);在C++11中,我们可以使用以下语法来进行替换:
int arr[3]{1, 2, 3};
vector<int> iv{1, 2, 3};
map<int, string>{{1, "a"}, {2, "b"}};
string str{"Hello World"};alignof和alignas
C++11标准中,为了支持对齐,引入了两个关键字:操作符alignof和对齐描述符alignas。
操作符alignof:用于返回类的对齐方式,即对齐值
对齐描述符alignas:用于设置类使用哪种对齐方式
struct alignas(32) A
{
char a;
int b;
};
int main()
{
//由于用alignas设置了对齐方式,原本大小为8字节的类A变为32字节了
cout << sizeof(A) << endl; //输出:32
cout << alignof(A) << endl; //输出:32
//alignas既可以接受常量表达式,也可以接受类型作为参数
alignas(8) int a;
alignas(alignof(double)) int b;
}C++11标准中规定了一个“基本对齐值”。一般情况下其值等于平台上支持的最大标量类型数据的对齐值。我们可以通过alignof(std::max_align_t)来查询其值。而像之前我们把对齐值设置为32位的做法称为扩展对齐,这按照C++标准该程序是不规范的,可能会导致未知的编译错误或者运行时错误。
其余对齐方式有STL库函数(std::align),还有STL库模板类型(aligned_storage和aligned_union)。