c++14新特性

1、函数返回值类型推导

c++14对函数返回类型推导规则做了优化:

auto func(int i) {  //C++11编译非法,c++14支持auto返回值类型推导
    return i;
}
int main() {
    cout << func(4) << endl;
    return 0;
}

支持函数模块返回值类型推导:

template<typename T>
auto func(T t) { return t; }

int main() {
    cout << func(4) << endl;
    cout << func(3.4) << endl;
    return 0;
}

auto返回值用例:

// 编译失败,多个return语句必须返回相同类型。
auto func(bool flag) {
    if (flag) return 1;
    else return 2.3;
}

// 编译失败,不能返回初始化列表
auto func1() {
    return {1, 2, 3};
}

//虚函数不能返回类型推导
class A{
    virtual auto func() { return 1; }
};

//返回值类型推导可以提前前声明,但使用前必须进行函数定义。
auto f();               // declared, not yet defined
auto f() { return 42; } // defined, return type is int

// 回类型推导可以用在递归函数中,但是递归调用必须以至少一个返回语句作为先导,以便编译器推导出返回类型。
auto sum(int i) {
    if (i == 1)
        return i;              // return int
    else
        return sum(i - 1) + i; // ok
}

int main() {
    cout << f() << endl;
    return 0;
}

2、lambda参数auto

在c++11中,lambda表达式参数需要使用具体的类型声明。

auto f = [] (int a) { return a; }

在c++14中,lambda表达式参数可以直接为auto。

auto f = [] (auto a) { return a; };
cout << f(1) << endl;
cout << f(2.3f) << endl;

3、变量模板

c++14支持变量模板。

template<class T>
constexpr T pi = T(3.1415926535897932385L);

int main() {
    cout << pi<int> << endl; // 3
    cout << pi<double> << endl; // 3.14159
    return 0;
}

4、别名模板

c++14支持别名模板。

template<typename T, typename U>
struct A {
    T t;
    U u;
};

template<typename T>
using B = A<T, int>;

int main() {
    B<double> b;
    b.t = 10;
    b.u = 20;
    cout << b.t << endl;
    cout << b.u << endl;
    return 0;
}

5、constexpr的限制

1)c++14相较于c++11减少了限制:

c++11和c++14中constexpr函数均可以使用递归。

constexpr int factorial(int n) { // C++14 和 C++11均可
    return n <= 1 ? 1 : (n * factorial(n - 1));
}

c++14还可以使用局部变量和循环。

constexpr int factorial(int n) { // C++11中不可,C++14中可以
    int ret = 0;
    for (int i = 0; i < n; ++i) {
        ret += i;
    }
    return ret;
}

c++11中constexpr函数中必须把所有东西放在一个单独的return语句中。

constexpr int func(bool flag) { // C++14 和 C++11均可
    return 0;
}

c++14中constexpr函数没有上述限制。

constexpr int func(bool flag) { // C++11中不可,C++14中可以
    if (flag) return 1;
    else return 0;
}

6、[[deprecated]]标记

c++14中增加deprecated标记,修饰类、变量、函数等。编译时产生警告,提醒用户该标记修饰的内容未来可能会被丢弃。

struct [[deprecated]] A { };

int main() {
    A a;
    return 0;
}

7、二进制字面量与字面量分隔符

c++14引入了二进制字面量和字面量分隔符。

int a = 0b0001'0011'1010;
double b = 3.14'1234'1234'1234;

8、std::make_unique

c++11中有std::make_shared,c++14增加了std::make_unique。 

struct A {};
std::unique_ptr<A> ptr = std::make_unique<A>();

9、std::shared_timed_mutex与std::shared_lock

c++14通过std::shared_timed_mutex和std::shared_lock来实现读写锁,保证多个线程可以同时读,但是写线程必须独立运行,写操作和读操作不可同时进行,这种情况下才能从shared_mutex中获取性能优势。

c++11 中互斥量

互斥量 说明
std::mutex 独占的互斥量,不能递归使用
std::timed_mutex 有超时能力的独占互斥量,不能递归使用
std::recursive_mutex 递归互斥量
std::recursive_timed_mutex 有超时能力的递归互斥量

c++14互斥量管理类-锁

  • shared_lock是read lock。搭配std::shared_mutex使用,被锁定后允许其它线程执行同样被shared_lock的代码。
  • lock_gurd和unique_lock是write lock。被锁定后,不允许其它线程执行被share_lock或unique_lock的代码。

通常这样定义:

typedef std::shared_lock<std::shared_mutex> ReadLock;
typedef std::lock_guard<std::shared_mutex> WriteLock;

实现方式:

struct ThreadSafe {
    mutable std::shared_timed_mutex mutex_;
    int value_;

    ThreadSafe() {
        value_ = 0;
    }

    int get() const {
        std::shared_lock<std::shared_timed_mutex> lock(mutex_);
        return value_;
    }

    void increase() {
        std::unique_lock<std::shared_timed_mutex> lock(mutex_);
        value_ += 1;
    }
};

10、 std::integer_sequence

表示一个编译时的整型序列。

11、std::exchange

以 new_value 替换 obj 的值,并返回 obj 的旧值。注意与std::swap的区别。

vector<int> v{4,5,6,7};
vector<int> x = std::exchange(v, {1,2,3,4});
cout << v.size() << endl;
for (int a : v) {
       cout << a << " ";
}
cout<<endl;
for (int a : x) {
      cout << a << " ";
}

 12、std::quoted

c++14引入std::quoted用于给字符串添加双引号。

string str = "hello world";
cout << str << endl;
cout << std::quoted(str) << endl;
/* 输出
* hello world
* "hello world"
*/

 

posted @ 2021-03-25 14:35  钟齐峰  阅读(570)  评论(0编辑  收藏  举报