Skip to content

高级特性

本章将介绍C++11/14/17/20标准引入的新特性,帮助您了解现代C++的发展趋势。

C++11新特性

cpp
#include <iostream>
#include <vector>
#include <memory>
#include <functional>
using namespace std;

int main() {
    // ============ auto关键字 ============
    
    auto num = 10;           // int
    auto pi = 3.14;          // double
    auto str = "hello";      // const char*
    
    vector<int> vec = {1, 2, 3, 4, 5};
    auto it = vec.begin();   // vector<int>::iterator
    
    cout << "auto推导类型" << endl;
    
    
    // ============ 范围for循环 ============
    
    cout << "\n范围for: ";
    for (auto n : vec) {
        cout << n << " ";
    }
    cout << endl;
    
    // 引用修改
    for (auto& n : vec) {
        n *= 2;
    }
    
    
    // ============ 初始化列表 ============
    
    vector<int> v1 = {1, 2, 3, 4, 5};
    vector<int> v2{1, 2, 3, 4, 5};
    
    int arr[] = {1, 2, 3, 4, 5};
    int arr2[]{1, 2, 3, 4, 5};
    
    
    // ============ nullptr ============
    
    int* ptr = nullptr;  // 替代NULL
    if (ptr == nullptr) {
        cout << "\nptr是空指针" << endl;
    }
    
    
    // ============ 强类型枚举 ============
    
    enum class Color { Red, Green, Blue };
    enum class Size : char { Small, Medium, Large };
    
    Color c = Color::Red;
    // int n = c;  // 错误:不能隐式转换
    int n = static_cast<int>(c);  // 需要显式转换
    
    
    // ============ constexpr ============
    
    constexpr int square(int x) {
        return x * x;
    }
    
    constexpr int val = square(5);  // 编译时计算
    cout << "\nsquare(5) = " << val << endl;
    
    
    // ============ 右值引用和移动语义 ============
    
    string s1 = "Hello";
    string s2 = move(s1);  // 移动而非拷贝
    
    cout << "s1: \"" << s1 << "\"" << endl;  // s1可能为空
    cout << "s2: \"" << s2 << "\"" << endl;
    
    
    // ============ Lambda表达式 ============
    
    auto add = [](int a, int b) { return a + b; };
    cout << "\nLambda: 10 + 20 = " << add(10, 20) << endl;
    
    int x = 10;
    auto addX = [x](int a) { return a + x; };
    cout << "捕获x: 5 + 10 = " << addX(5) << endl;
    
    auto addXRef = [&x](int a) { x++; return a + x; };
    cout << "引用捕获: 5 + " << x + 1 << " = " << addXRef(5) << endl;
    
    
    // ============ 智能指针 ============
    
    auto up = make_unique<int>(42);
    auto sp = make_shared<int>(100);
    
    cout << "\nunique_ptr: " << *up << endl;
    cout << "shared_ptr: " << *sp << endl;
    
    
    // ============ 可变参数模板 ============
    
    auto printAll = [](auto... args) {
        (cout << ... << args) << endl;  // C++17折叠表达式
    };
    
    cout << "\n可变参数: ";
    printAll(1, " + ", 2, " = ", 3);
    
    
    // ============ std::function ============
    
    function<int(int, int)> operation = add;
    cout << "\nfunction: " << operation(5, 3) << endl;
    
    operation = [](int a, int b) { return a * b; };
    cout << "function(乘法): " << operation(5, 3) << endl;
    
    return 0;
}

C++14新特性

cpp
#include <iostream>
#include <memory>
using namespace std;

int main() {
    // ============ 泛型Lambda ============
    
    // C++11:需要指定参数类型
    // auto add11 = [](int a, int b) { return a + b; };
    
    // C++14:自动推导参数类型
    auto add = [](auto a, auto b) {
        return a + b;
    };
    
    cout << "泛型Lambda:" << endl;
    cout << "  int: " << add(1, 2) << endl;
    cout << "  double: " << add(1.5, 2.5) << endl;
    cout << "  string: " << add(string("Hello"), string(" World")) << endl;
    
    
    // ============ 返回类型推导 ============
    
    // C++11:需要尾置返回类型
    // auto func11() -> int { return 42; }
    
    // C++14:自动推导
    auto func = []() {
        return 42;  // 自动推导为int
    };
    
    cout << "\n返回类型推导: " << func() << endl;
    
    
    // ============ decltype(auto) ============
    
    int x = 10;
    int& ref = x;
    
    auto a = ref;        // int(丢失引用)
    decltype(auto) b = ref;  // int&(保留引用)
    
    b = 20;
    cout << "\ndecltype(auto): x = " << x << endl;  // x变为20
    
    
    // ============ 二进制字面量 ============
    
    int binary = 0b1010;  // 二进制10
    cout << "\n二进制0b1010 = " << binary << endl;
    
    
    // ============ 数字分隔符 ============
    
    int million = 1'000'000;  // 提高可读性
    double pi = 3.141'592'653;
    
    cout << "数字分隔符: " << million << ", " << pi << endl;
    
    
    // ============ make_unique ============
    
    auto ptr = make_unique<int>(42);
    cout << "\nmake_unique: " << *ptr << endl;
    
    auto arr = make_unique<int[]>(5);
    for (int i = 0; i < 5; i++) {
        arr[i] = i * 10;
    }
    
    cout << "make_unique数组: ";
    for (int i = 0; i < 5; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
    
    return 0;
}

C++17新特性

cpp
#include <iostream>
#include <optional>
#include <variant>
#include <any>
#include <string_view>
using namespace std;

int main() {
    // ============ 结构化绑定 ============
    
    pair<int, string> p = {1, "hello"};
    auto [id, name] = p;  // 解构
    
    cout << "结构化绑定: id = " << id << ", name = " << name << endl;
    
    int arr[] = {1, 2, 3};
    auto [a, b, c] = arr;
    cout << "数组解构: " << a << ", " << b << ", " << c << endl;
    
    
    // ============ if初始化语句 ============
    
    // 在if条件中声明变量
    if (int x = 10; x > 5) {
        cout << "\nif初始化: x = " << x << endl;
    }
    // x在这里不可见
    
    // 用于资源管理
    if (auto ptr = make_unique<int>(42); *ptr == 42) {
        cout << "ptr值正确: " << *ptr << endl;
    }
    
    
    // ============ std::optional ============
    
    auto findValue = [](int key) -> optional<int> {
        if (key > 0) {
            return key * 10;
        }
        return nullopt;  // 无值
    };
    
    auto result1 = findValue(5);
    if (result1) {
        cout << "\noptional有值: " << *result1 << endl;
    }
    
    auto result2 = findValue(-1);
    cout << "optional无值: " << result2.value_or(0) << endl;
    
    
    // ============ std::variant ============
    
    variant<int, double, string> v;
    
    v = 42;
    cout << "\nvariant(int): " << get<int>(v) << endl;
    
    v = 3.14;
    cout << "variant(double): " << get<double>(v) << endl;
    
    v = "hello";
    cout << "variant(string): " << get<string>(v) << endl;
    
    // 安全访问
    if (holds_alternative<string>(v)) {
        cout << "当前是string类型" << endl;
    }
    
    
    // ============ std::any ============
    
    any a = 42;
    cout << "\nany(int): " << any_cast<int>(a) << endl;
    
    a = 3.14;
    cout << "any(double): " << any_cast<double>(a) << endl;
    
    a = string("hello");
    cout << "any(string): " << any_cast<string>(a) << endl;
    
    
    // ============ std::string_view ============
    
    // 非拥有的字符串视图,避免拷贝
    string str = "Hello, World!";
    string_view sv = str;
    
    cout << "\nstring_view: " << sv << endl;
    cout << "子串: " << sv.substr(0, 5) << endl;
    
    // 可以指向字符串字面量
    string_view literal = "Hello C++17";
    cout << "字面量: " << literal << endl;
    
    
    // ============ 折叠表达式 ============
    
    // 一元右折叠
    auto sum = [](auto... args) {
        return (args + ...);
    };
    
    cout << "\n折叠表达式: " << sum(1, 2, 3, 4, 5) << endl;
    
    // 一元左折叠
    auto product = [](auto... args) {
        return (... * args);
    };
    
    cout << "乘积: " << product(1, 2, 3, 4, 5) << endl;
    
    
    // ============ if constexpr ============
    
    auto process = [](auto value) {
        if constexpr (is_integral_v<decltype(value)>) {
            cout << "\n整数: " << value << endl;
        } else if constexpr (is_floating_point_v<decltype(value)>) {
            cout << "浮点: " << value << endl;
        } else {
            cout << "其他: " << value << endl;
        }
    };
    
    process(42);
    process(3.14);
    process("hello");
    
    return 0;
}

C++20新特性

cpp
#include <iostream>
#include <vector>
#include <span>
#include <concepts>
using namespace std;

// ============ 概念(Concepts) ============

// 定义概念
template<typename T>
concept Numeric = is_arithmetic_v<T>;

// 使用概念约束模板参数
template<Numeric T>
T add(T a, T b) {
    return a + b;
}

// 更复杂的概念
template<typename T>
concept Printable = requires(T t, ostream& os) {
    { os << t } -> same_as<ostream&>;
};

template<Printable T>
void print(const T& value) {
    cout << value << endl;
}

// ============ 范围库 ============

// C++20 ranges(简化版示例)
void rangesExample() {
    vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    // 使用范围适配器(需要<ranges>头文件)
    // auto even = numbers | views::filter([](int n) { return n % 2 == 0; })
    //                     | views::transform([](int n) { return n * 2; });
    
    cout << "范围库示例(需要完整支持)" << endl;
}

int main() {
    // ============ 概念 ============
    
    cout << "===== 概念 =====" << endl;
    cout << "add(1, 2) = " << add(1, 2) << endl;
    cout << "add(1.5, 2.5) = " << add(1.5, 2.5) << endl;
    // add("hello", "world");  // 编译错误:不满足Numeric概念
    
    print(42);
    print(string("hello"));
    
    
    // ============ std::span ============
    
    cout << "\n===== std::span =====" << endl;
    
    int arr[] = {1, 2, 3, 4, 5};
    span<int> s(arr);
    
    cout << "span: ";
    for (int n : s) {
        cout << n << " ";
    }
    cout << endl;
    
    // 子span
    span<int> sub = s.subspan(1, 3);
    cout << "子span: ";
    for (int n : sub) {
        cout << n << " ";
    }
    cout << endl;
    
    
    // ============ 三向比较运算符 <=> ============
    
    cout << "\n===== 三向比较 =====" << endl;
    
    int a = 10, b = 20;
    auto result = a <=> b;
    
    if (result < 0) cout << "a < b" << endl;
    else if (result > 0) cout << "a > b" << endl;
    else cout << "a == b" << endl;
    
    
    // ============ 指定初始化器 ============
    
    cout << "\n===== 指定初始化器 =====" << endl;
    
    struct Point {
        int x;
        int y;
        int z = 0;
    };
    
    Point p1 = {.x = 10, .y = 20};
    Point p2 = {.x = 1, .y = 2, .z = 3};
    
    cout << "p1: (" << p1.x << ", " << p1.y << ", " << p1.z << ")" << endl;
    cout << "p2: (" << p2.x << ", " << p2.y << ", " << p2.z << ")" << endl;
    
    
    // ============ constinit ============
    
    // 确保编译时初始化
    constinit static int globalValue = 42;
    cout << "\nconstinit: " << globalValue << endl;
    
    
    // ============ 协程(简化说明) ============
    
    cout << "\n===== 协程 =====" << endl;
    cout << "C++20引入协程支持,可用于异步编程" << endl;
    cout << "需要co_await、co_yield、co_return关键字" << endl;
    
    
    // ============ 模块(简化说明) ============
    
    cout << "\n===== 模块 =====" << endl;
    cout << "C++20引入模块系统,替代头文件" << endl;
    cout << "使用import和export关键字" << endl;
    
    return 0;
}

本章小结

本章学习了:

  • C++11:auto、范围for、Lambda、智能指针、右值引用
  • C++14:泛型Lambda、返回类型推导、二进制字面量
  • C++17:结构化绑定、optional、variant、string_view、折叠表达式
  • C++20:概念、span、三向比较、协程、模块

掌握现代C++特性,可以编写更简洁、更安全、更高效的代码。