C++14:增量改进

C++14 是一个较小的更新,主要是对 C++11 的改进和补充。

泛型 Lambda

// C++11 只能指定具体类型
auto lambda1 = [](int x) { return x * 2; };

// C++14 支持 auto 参数
auto lambda2 = [](auto x) { return x * 2; };
lambda2(3);      // int
lambda2(3.14);   // double

Lambda 捕获初始化

int x = 42;
auto lambda = [y = x + 1]() { return y; };
// y 是 43,即使 x 改变也不影响

// 更复杂的捕获
auto ptr = std::make_unique<int>(100);
auto capturePtr = [p = std::move(ptr)]() { return *p; };

函数返回类型推导

// C++11 必须指定返回类型
auto add1(int x, int y) -> int {
    return x + y;
}

// C++14 可以推导返回类型
auto add2(int x, int y) {
    return x + y;
}

// 递归函数需要指定返回类型
auto factorial(int n) -> int {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

变量模板

template<typename T>
constexpr T pi = T(3.1415926535897932385);

double d = pi<double>;   // 3.1415926535897932385
float f = pi<float>;     // 3.1415927f

// 其他变量模板
template<typename T>
constexpr std::size_t byte_count = sizeof(T);

std::size_t size = byte_count<int>;  // 4

二进制字面量

int x = 0b1010;  // 10
int y = 0b11111111;  // 255
int z = 0b1100'0101;  // 197

// 无符号
unsigned int flags = 0b0000'1111'0000'0000;

数字分隔符

int million = 1'000'000;
double pi = 3.14159'26535;
int binary = 0b1010'0101;
long long credit = 1'000'000'000'000LL;

// 十六进制
uint32_t mac = 0xDE'AD'BE'EF;

[[deprecated]] 属性

[[deprecated("Use newFunction instead")]]
void oldFunction() {}

// 使用
[[deprecated]] int deprecatedVar = 42;

放宽 constexpr 限制

// C++14 constexpr 函数可以有局部变量和循环
constexpr int factorial(int n) {
    int result = 1;
    for (int i = 2; i <= n; ++i) {
        result *= i;
    }
    return result;
}

constexpr int f = factorial(5);  // 120

std::make_unique

// C++11 没有 make_unique
std::unique_ptr<int> ptr1(new int(42));

// C++14 添加了 make_unique
std::unique_ptr<int> ptr2 = std::make_unique<int>(42);

// 数组
auto arr = std::make_unique<int[]>(10);

// 更安全:异常安全
auto smartPtr = std::make_unique<MyClass>(args...);

std::quoted

#include <iomanip>
#include <sstream>

std::string input = R"(Hello "World"!)";
std::stringstream ss;
ss << std::quoted(input);
std::cout << ss.str() << "\n";  // 输出: "Hello \"World\"!"

// 读取
std::string output;
ss >> std::quoted(output);  // output = Hello "World"!

std::exchange

// C++11 需要手动实现
template<typename T, typename U>
T exchange(T& obj, U&& newValue) {
    T oldValue = std::move(obj);
    obj = std::forward<U>(newValue);
    return oldValue;
}

// C++14 直接使用
std::vector<int> v{1, 2, 3};
std::vector<int> old = std::exchange(v, {4, 5});
// old = {1, 2, 3}, v = {4, 5}

std::integer_sequence

#include <utility>

// 编译时整数序列
template<std::size_t... Ints>
void printIndices(std::index_sequence<Ints...>) {
    ((std::cout << Ints << " "), ...);
}

printIndices(std::make_index_sequence<5>{});  // 0 1 2 3 4

// 应用到参数包
template<typename T, std::size_t... Is>
void printTupleElements(const T& t, std::index_sequence<Is...>) {
    ((std::cout << std::get<Is>(t) << " "), ...);
}

chrono 和 string 字面量

using namespace std::chrono_literals;

// 时间字面量
auto duration = 100ms;           // 100 毫秒
auto seconds = 2s;               // 2 秒
auto minutes = 5min;             // 5 分钟
auto hours = 1h;                 // 1 小时

// 组合使用
auto complexDuration = 1h + 30min + 45s;

// 字符串字面量(C++14)
auto str = "hello"s;  // std::string
auto u8str = u8"world"s;  // std::string (UTF-8)
auto wstr = L"wide"s;  // std::wstring

std::shared_timed_mutex

#include <shared_mutex>

class ReaderWriter {
    mutable std::shared_timed_mutex mtx_;
    std::vector<int> data_;

public:
    void write(int value) {
        std::unique_lock<std::shared_timed_mutex> lock(mtx_);
        data_.push_back(value);
    }

    std::vector<int> read() const {
        std::shared_lock<std::shared_timed_mutex> lock(mtx_);
        return data_;
    }
};

std::shared_lock

#include <shared_mutex>

std::shared_timed_mutex mtx;

// 共享锁(读锁)
std::shared_lock<std::shared_timed_mutex> read_lock(mtx);
// 可以多个线程同时持有

// 独占锁(写锁)
std::unique_lock<std::shared_timed_mutex> write_lock(mtx);
// 独占访问

常用特性总结

最常用的 C++14 特性:

  • 泛型 Lambda
  • 函数返回类型推导
  • std::make_unique
  • 数字分隔符
  • 二进制字面量