【C/C++】C++11新特性

auto

自动推导类型。

    auto i = 10;

    std::cout << i << std::endl;

    double x = 12.34;
    auto *y = new auto(x);

    std::cout << *y << std::endl;

decltype

可以获取变量或值的类型名称,替换源码中的调用。

int x = 0;
decltype(x) y = x;

nullptr

空指针,指向地址0x000000的指针。与NULL的区别是,NULL是0的别名,原型为:#define NULL 0,调用NULL的地方相当于直接替换为0。

智能指针

#include <stdlib.h>
#include <iostream>
#include <memory>

void main(){
    // 建议在for前后断点观察进程占用内存
    for (int i = 0; i < 1000000; ++i)
    {
        double* p = new double;
        std::auto_ptr<double> ap (p); //C++98中的智能指针,依赖一个原生指针。在块结束时释放指针指向内存,相当于把堆当栈使用。
    }

    for (int i = 0; i < 1000000; ++i)
    {
        std::unique_ptr<double> ap (new double); //C++11中的智能指针,可直接使用原生指针初始化,当指针不被引用时释放指针指向内存。
    }

    system("pause");
}   

高级for

int arr[] = {1,2,3,4,5};
for( int i : arr ){
  std::cout<<i<<std::endl;
}

lambda表达式

lambda式的作用类似Java中的创建一个匿名函数对象。这样就可以省去定义很多只有一处地方使用的函数。

lambda表达式格式:[ 可访问外部变量列表 ]( 参数列表 ) ->返回值类型 {

函数体

}

std::array<int>(5) arr = {1,2,3,4,5};
int a = 1;
int b = 2; 

//1.访问指定外部变量的右值(右值在寄存器,不在内存,不存在地址,所以不能执行赋值操作)
for_each(arr.begin(), arr.end(), [ a, b ] ( int & i ) {
    std::cout<<a<<std::endl;
    std::cout<<b<<std::endl;
    //a = b; //error
}) 

//2.访问所有外部变量的右值
for_each(arr.begin(), arr.end(), [ = ] ( int & i ) {
    std::cout<<a<<std::endl;
    std::cout<<b<<std::endl;
}) 

//3.访问指定外部变量的左值
for_each(arr.begin(), arr.end(), [ &a, &b ] ( int & i ) {
    a = b = i;
    std::cout<<a<<std::endl;
    std::cout<<b<<std::endl;
})
//4.访问所有外部变量的左值
for_each(arr.begin(), arr.end(), [ & ] ( int & i ) {
    a = b = i;
    std::cout<<a<<std::endl;
    std::cout<<b<<std::endl;
})
//5.定义一个有返回值的lambda表达式
auto fun =  [ ] ( int & a , int & b) ->int {
    return a+b;
})
int result = fun(arr[0], arr[0]);

tuple

tuple是一个多元组,可以包含多个不同类型的数据。

// tuple example
#include <iostream>     // std::cout
#include <tuple>        // std::tuple, std::get, std::tie, std::ignore

int main ()
{
  std::tuple<int,char> foo (10,‘x‘);
  auto bar = std::make_tuple ("test", 3.1, 14, ‘y‘);

  std::get<2>(bar) = 100;                                    // 访问tuple中的元素

  int myint; char mychar;

  std::tie (myint, mychar) = foo;                            // unpack elements
  std::tie (std::ignore, std::ignore, myint, mychar) = bar;  // unpack (with ignore),std::ignore用于忽略指定位置的元素

  mychar = std::get<3>(bar);

  std::get<0>(foo) = std::get<2>(bar);
  std::get<1>(foo) = mychar;

  std::cout << "foo contains: ";
  std::cout << std::get<0>(foo) << ‘ ‘;
  std::cout << std::get<1>(foo) << ‘\n‘;

  return 0;
}

可变参数列表

#include<cstdarg> //用于处理可变参数列表的库

template<typename T>
T sum(int count, T data1, ...) // data1用于限定可变参数列表至少需要一个参数
{
    va_list arg_ptr; //定义可变参数列表指针
    va_start(arg_ptr, count); //初始化可变参数列表,限定从count后面开始
    T total = 0;
    for(int i=0; i<count; ++i){
        total += va_arg(arg_ptr, T); // 取可变参数列表中的参数进行累加
    }
    va_end(arg_ptr); //结束可变参数列表指针的使用
    return total;
}

可变参数模板

#include<iostream>

template<typename... Arguments>
void func(const Arguments&... args)
{
    const unsigned size= sizeof...(Arguments); // sizeof...操作符可获取可变参数列表的参数个数

    std::cout << size<< std::endl;

    printf(args...);
}

void main(){
    func("%d%d%d%d",1, 2, 3, 4);
}   

使用{}初始化

在C++11之前,只有数组可以使用{}初始化。C++11之后stl中的容器也可以使用{}初始化了。

//C++11 之前:
std::map<int,string> map;
map[1] = "a";
map[2] = "b"; 
//C++11之后:
std::map<int,string> map = { {1,"a"}, {2,"b"} }; 

类成员变量初始化默认值

在C++11之前,类的成员变量如果想初始化一个默认值只能通过构造函数去初始化,但如果有多个构造函数,这时初始化就变得麻烦了,每个构造都需要初始化,或者通过一个构造调用另一构造方式初始化。

C++11之前

class A{
private:
    int i;
public:
    A():i(1){} //初始化i为1
    A(string str):i(1){} //初始化i为1
};

class A{
private:
    int i;
public:
    A() :i(1){} //初始化i为1
    A(string str):A(){  } //调用空构造,初始化i为1
};

在C++11之后

class A{
private:
    int i = 1; //给成员变量设置默认初始值
public:
    A(){}
    A(string str){}
};
时间: 2024-08-17 06:45:58

【C/C++】C++11新特性的相关文章

C++11 新特性之 tuple

我们在C++中都用过pair.pair是一种模板类型,其中包含两个数据值,两个数据的类型可以不同.pair可以使用make_pair构造 pair<int, string> p = make_pair(1, "a1"); 如果传入的参数为多个,那么就需要嵌套pair,如下代码 #include <iostream> #include <map> using namespace std; int main() { //<int, string,

C++11 新特性之 变长参数模板

template <typename ... ARGS> void fun(ARGS ... args) 首先明确几个概念 1,模板参数包(template parameter pack):它指模板参数位置上的变长参数,例如上面例子中的ARGS 2,函数参数包(function parameter pack):它指函数参数位置上的变长参数,例如上面例子中的args 一般情况下 参数包必须在最后面,例如: template <typename T, typename ... Args>

【C++11】30分钟了解C++11新特性

作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 什么是C++11 C++11是曾经被叫做C++0x,是对目前C++语言的扩展和修正,C++11不仅包含核心语言的新机能,而且扩展了C++的标准程序库(STL),并入了大部分的C++ Technical Report 1(TR1)程序库(数学的特殊函数除外). C++11包括大量的新特性:包括lambda表达式,类型推导关键字auto.decl

[C++11新特性]第二篇

0.可变数量参数,可变函数模版,变长模版类 c++98可变数量参数 #include<cstdio> #include<cstdarg> double SumOfFloat(int count, ...) { va_list ap; double sum=0; va_start(ap,count); for(int i=0;i<count;i++) sum+=va_arg(ap,double); va_end(ap); return sum; } int main() { p

C++11 新特性(5) 统一初始化

在C++11之前,初始化的类型并非总是统一的. 例如以下两个man定义,一个作为结构,一个作为类.两者的初始化是不一样的. #include <iostream> using namespace std; struct manStruct{ string name; int age; }; class manClass { private: string name; int age; public: manClass(string s,int a):name(s),age(a){ } }; i

[cocos2d-x] 一些C++ 11新特性的引入

1.auto关键字的使用 auto关键字原理     在定义变量的时候必须申明类型,c++是强语言类型,在编译阶段需要知道类型,这样的好处是程序效率更高,而动态语言不需要类型申明的需要自推导变量类型.使用了auto是不是c++效率会变慢?完全不是,因为在编译阶段编译器已经帮程序员推导好了变量的类型.前提条件是编译器可以根据当前的程序的状态推导出变量类型.只是编译器更加智能,可能会增加编译工作,但是不会影响运行效率. 实例1:申明普通变量 auto num = 10; 实例2: vector<st

c++11 新特性之 auto关键字

C++11是对目前C++语言的扩展和修正.C++11包括大量的新特性:包括lambda表达式,类型推导关键字auto.decltype,和模板的大量改进. g++编译c++11命令加上 -std=c++11 C++11中引入auto第一种作用是为了自动类型推导 auto的自动类型推导,用于从初始化表达式中推断出变量的数据类型.通过auto的自动类型推导,可以简化我们的编程工作 auto实际上实在编译时对变量进行了类型推导,所以不会对程序的运行效率造成不良影响另外,似乎auto并不会影响编译速度,

C++11 新特性之 decltype关键字

decltype关键字用于查询表达式的类型.与其他特性结合起来之后会有意想不到的效果. decltype的语法是 decltype (expression) 实例: #include <iostream> #include <typeinfo> using namespace std; int main() { int i; double d; float f; struct A { int i; double d; }; decltype(i) i1; cout <<

C++11 新特性(6) 基于范围的for循环

C++11中添加了一项基于范围的for循环,这可以省却我们很多的代码量. 来自维基百科的解释:http://zh.wikipedia.org/wiki/C++0x#.E5.80.99.E9.81.B8.E8.AE.8A.E6.9B.B4 Boost C++ 定义了许多"范围 (range) "的概念.范围表现有如受控制的列表 (list),持有容器中的两点.有序容器是范围概念的超集 (superset),有序容器中的两个迭代器 (iterator) 也能定义一个范围.这些概念以及操作的

C++11新特性:自动类型推断和类型获取

声明:本文是在Alex Allain的文章http://www.cprogramming.com/c++11/c++11-auto-decltype-return-value-after-function.html的基础上写成的. 加入了很多个人的理解,不是翻译. 转载请注明出处 http://blog.csdn.net/srzhz/article/details/7934483 自动类型推断 当编译器能够在一个变量的声明时候就推断出它的类型,那么你就能够用auto关键字来作为他们的类型: [c