[C/C++] C++2.0新特性学习

一、判断编译器是否支持

编译器支持的C++版本,我们只需要打印__cplusplus常量就可以知晓:

cout<<__cpluscplus<<endl;

如果打印2011**则是C++11版本,打印2014**就是C++14版本,打印1997**则是C++1.0版本。
如果使用新版本的IDE,打印发现是1997**,则说明IDE要开启C++2.0的支持,需要进行配置,可以google以下如果配置即可。

二、Variadic Templates(不定数量模板参数)

1.使用不定数量模板参数简单例子

在之前的C++版本中,使用模板可以实现对任意类型数据参数的传递。在2.0版本中,我们可以传入不定数量的模板参数:

#include <iostream>
#include <bitset>

using namespace std;

// 3.必须定义一个无参数的空print函数来处理递归最后args中参数为0个的情况
void print(){}

// 1.从第二个参数开始,可以传入任意个数的参数,而且类型是任意的。注意'...'的位置
template<typename T, typename... Types>
// 2.这个函数完成了一个递归的操作,每次将args参数包中的第一个分离出来,剩下的再次递归
// 但是这里要非常注意,当args中的参数为0个时,则会调用上面的print()无参数版,所以这个无参数版的print()一定要定义,否则编译出错
void print(const T &firstArg, const Types &... args) {
    cout << firstArg << endl;
    print(args...);
}

int main() {
    // 第一个参数是float,后面的不定数量参数分别是字符串,bitset以及整数。
    print(7.5, "Hello", bitset<16>(377), 42);
    return 0;
}    

这里最需要注意的就是"..."的位置,以及最后递归收敛时的无参数print()函数。

2.使用不定模板参数例子二

实现一个简单的tuple类。用于同时保存不同类型、不同数量的数据。

#include <iostream>
#include <string>

using namespace std;

template<typename... Values>
class MyTuple;

template<>
class MyTuple<> {
};

// 定义一个模板,包含一个类型Head和一包类型Tail
template<typename Head, typename... Tail>
// 定义一个类,继承于比他自己少第一个参数的父类
class MyTuple<Head, Tail...> : private MyTuple<Tail...> {
    // 将父类定义别名为inherited
    typedef MyTuple<Tail...> inherited;
public:
    MyTuple() {}

    // 构造函数,v赋值给m_head,vtail传递给父类构造函数
    MyTuple(Head v, Tail... vtail) : m_head(v), inherited(vtail...) {}

    // 获取当前m_head
    Head head() { return m_head; }

    // return后,转型为父类类型,这样再次获取head(),就可以获取到下一个m_head
    inherited &tail() { return *this; }

protected:
    // 第一个元素
    Head m_head;
};


int main() {
    MyTuple<int, float, long, string> t(41, 6.3, 50000, "Good");
    cout << t.head() << endl;  // 打印41
    cout << t.tail().head() << endl;  // 打印6.3
    cout << t.tail().tail().head() << endl;  // 打印50000
    cout << t.tail().tail().tail().head() << endl;  // 打印Good
    return 0;
}

三、nullptr

在2.0版本以前,表示空指针可以使用0和NULL:

// 以前使用的两种初始化指针为空的方式
void * ptr = NULL;
void * ptr = 0;

在2.0中,空指针有一个特殊的值来代替,就是nullptr:

void * ptr1 = NULL;
void * ptr2 = 0;
void * ptr3 = nullptr;  // C++2.0的新关键字

另外还有一个nullptr_t是nullptr的类型,即decltype(nullptr),值是void *。

这样就可以通过这个初始化的值来区分需要调用的函数,例如:

void * func(int);
void *func(void *);
func(0);  // 调用func(int)
func(NULL);  // 调用func(int)
func(nullptr);  // 调用func(void *)

四、auto关键字

auto关键字是C++2.0的新的关键字,用来自动推导变量的类型。

例如:

auto i = 43; // i是int
double f();
auto d = f(); // d是double类型,自动从f()的返回值推导

推导比较长的类型(偷懒):

vector<string> v;
auto pos = v.begin();  // pos的类型为vector<string>::iterator

推导很难的类型:

auto lf = [](int x)->bool{  ...  };  // lf的类型时lambda函数

 

 

 

 

posted @ 2020-03-18 10:04  风间悠香  阅读(421)  评论(0编辑  收藏  举报