乐闻世界logo
搜索文章和话题

C++11/14/17/20 新特性有哪些

2月18日 17:36

C++11/14/17/20 新特性

C++ 标准不断演进,每个新版本都引入了许多强大的特性,显著提升了开发效率和代码质量。

C++11 新特性

自动类型推导(auto):

cpp
// 自动推导类型 auto x = 42; // int auto y = 3.14; // double auto z = "Hello"; // const char* auto& ref = x; // int& auto&& universal = x; // int& (万能引用) // 与迭代器配合使用 std::vector<int> vec = {1, 2, 3}; for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << std::endl; } // 范围 for 循环 for (auto& val : vec) { val *= 2; }

范围 for 循环:

cpp
std::vector<int> vec = {1, 2, 3, 4, 5}; // 只读遍历 for (const auto& val : vec) { std::cout << val << " "; } // 修改遍历 for (auto& val : vec) { val *= 2; } // 初始化列表 for (auto val : {1, 2, 3, 4, 5}) { std::cout << val << " "; }

Lambda 表达式:

cpp
// 基本语法 auto lambda = [](int x, int y) { return x + y; }; // 捕获变量 int threshold = 10; auto filtered = [threshold](int x) { return x > threshold; }; // 引用捕获 int sum = 0; auto accumulate = [&sum](int x) { sum += x; }; // 混合捕获 int a = 1, b = 2; auto mixed = [a, &b]() { return a + b; }; // 可变 lambda auto variadic = [](auto... args) { return (args + ... + 0); }; // 使用 std::vector<int> vec = {5, 15, 25}; auto it = std::find_if(vec.begin(), vec.end(), filtered);

智能指针:

cpp
#include <memory> // unique_ptr - 独占所有权 auto ptr1 = std::make_unique<int>(42); auto ptr2 = std::move(ptr1); // 转移所有权 // shared_ptr - 共享所有权 auto shared1 = std::make_shared<int>(100); auto shared2 = shared1; // 引用计数增加 std::cout << shared1.use_count() << std::endl; // 2 // weak_ptr - 弱引用 std::weak_ptr<int> weak = shared1; if (auto locked = weak.lock()) { std::cout << *locked << std::endl; }

右值引用与移动语义:

cpp
class MyString { private: char* data; size_t size; public: MyString(const char* str = ""); MyString(const MyString& other); // 拷贝构造 MyString(MyString&& other) noexcept; // 移动构造 MyString& operator=(const MyString& other); // 拷贝赋值 MyString& operator=(MyString&& other) noexcept; // 移动赋值 }; // 使用 MyString str1 = "Hello"; MyString str2 = std::move(str1); // 移动而非拷贝

nullptr:

cpp
// C++11 之前 int* ptr1 = NULL; void func(int* ptr); void func(int value); func(NULL); // 歧义,可能调用 func(int) // C++11 int* ptr2 = nullptr; func(nullptr); // 明确调用 func(int*)

constexpr:

cpp
// 编译期常量 constexpr int factorial(int n) { return n <= 1 ? 1 : n * factorial(n - 1); } constexpr int result = factorial(5); // 编译期计算 // 字面量类型 struct Point { constexpr Point(double x, double y) : x(x), y(y) {} constexpr double distance() const { return x * x + y * y; } double x, y; }; constexpr Point p(3.0, 4.0); constexpr double dist = p.distance(); // 25.0

C++14 新特性

泛型 lambda:

cpp
// C++11 auto add = [](int a, int b) { return a + b; }; // C++14 - 泛型 lambda auto genericAdd = [](auto a, auto b) { return a + b; }; auto result1 = genericAdd(10, 20); // int auto result2 = genericAdd(3.14, 2.71); // double

变量模板:

cpp
template <typename T> constexpr T pi = T(3.1415926535897932385); // 使用 double d = pi<double>; float f = pi<float>;

二进制字面量:

cpp
int binary = 0b1010; // 10 int octal = 012; // 10 int hex = 0xA; // 10

函数返回类型推导:

cpp
// C++11 auto add(int a, int b) -> int { return a + b; } // C++14 - 自动推导返回类型 auto add(int a, int b) { return a + b; } // 复杂返回类型 auto getVector() { return std::vector<int>{1, 2, 3}; }

std::make_unique:

cpp
// C++11 auto ptr = std::unique_ptr<int>(new int(42)); // C++14 auto ptr = std::make_unique<int>(42);

C++17 新特性

结构化绑定:

cpp
std::map<int, std::string> myMap = {{1, "one"}, {2, "two"}}; // C++17 之前 for (auto it = myMap.begin(); it != myMap.end(); ++it) { int key = it->first; std::string value = it->second; } // C++17 for (const auto& [key, value] : myMap) { std::cout << key << ": " << value << std::endl; } // 元组解包 auto [x, y, z] = std::make_tuple(1, 2.0, "three");

if constexpr:

cpp
template <typename T> auto process(T value) { if constexpr (std::is_integral_v<T>) { return value * 2; } else if constexpr (std::is_floating_point_v<T>) { return value / 2; } else { return value; } } // 使用 process(10); // 20 process(3.14); // 1.57

std::optional:

cpp
#include <optional> std::optional<int> divide(int a, int b) { if (b == 0) { return std::nullopt; } return a / b; } // 使用 auto result = divide(10, 2); if (result) { std::cout << *result << std::endl; } else { std::cout << "Division by zero" << std::endl; } // 提供默认值 int value = result.value_or(0);

std::variant:

cpp
#include <variant> std::variant<int, double, std::string> value; value = 42; value = 3.14; value = "Hello"; // 访问 std::visit([](auto&& arg) { std::cout << arg << std::endl; }, value); // 检查类型 if (std::holds_alternative<int>(value)) { int intValue = std::get<int>(value); }

std::any:

cpp
#include <any> std::any value = 42; value = 3.14; value = "Hello"; // 访问 if (value.type() == typeid(int)) { int intValue = std::any_cast<int>(value); }

折叠表达式:

cpp
// C++17 template <typename... Args> auto sum(Args... args) { return (args + ... + 0); } // 使用 auto total = sum(1, 2, 3, 4, 5); // 15 // 左折叠 template <typename... Args> bool allTrue(Args... args) { return (args && ...); } // 右折叠 template <typename... Args> void printAll(Args... args) { (std::cout << ... << args) << std::endl; }

std::string_view:

cpp
#include <string_view> void printString(std::string_view str) { std::cout << str << std::endl; } // 使用 std::string str = "Hello"; const char* cstr = "World"; printString(str); // OK printString(cstr); // OK printString("Test"); // OK,无需创建临时 string 对象

C++20 新特性

概念(Concepts):

cpp
#include <concepts> // 定义概念 template <typename T> concept Integral = std::is_integral_v<T>; template <typename T> concept Sortable = requires(T t) { { t.begin() } -> std::same_as<typename T::iterator>; { t.end() } -> std::same_as<typename T::iterator>; }; // 使用概念约束模板 template <Integral T> T add(T a, T b) { return a + b; } // requires 子句 template <typename T> requires std::is_integral_v<T> T multiply(T a, T b) { return a * b; } // 简写语法 void process(Integral auto value) { std::cout << value << std::endl; }

三向比较(Spaceship Operator):

cpp
struct Point { int x, y; // 自动生成比较运算符 auto operator<=>(const Point&) const = default; }; // 使用 Point p1{1, 2}; Point p2{1, 3}; if (p1 < p2) { std::cout << "p1 < p2" << std::endl; } if (p1 == p2) { std::cout << "p1 == p2" << std::endl; }

范围库(Ranges):

cpp
#include <ranges> #include <vector> #include <algorithm> std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 过滤偶数 auto evens = numbers | std::views::filter([](int n) { return n % 2 == 0; }); // 转换 auto squared = numbers | std::views::transform([](int n) { return n * n; }); // 组合操作 auto result = numbers | std::views::filter([](int n) { return n % 2 == 0; }) | std::views::transform([](int n) { return n * n; }); // 使用 for (auto n : result) { std::cout << n << " "; }

协程(Coroutines):

cpp
#include <coroutine> // 简单的生成器 template <typename T> struct Generator { struct promise_type { T current_value; Generator get_return_object() { return Generator{std::coroutine_handle<promise_type>::from_promise(*this)}; } std::suspend_always initial_suspend() { return {}; } std::suspend_always final_suspend() noexcept { return {}; } std::suspend_always yield_value(T value) { current_value = value; return {}; } void return_void() {} void unhandled_exception() { std::terminate(); } }; std::coroutine_handle<promise_type> handle; Generator(std::coroutine_handle<promise_type> h) : handle(h) {} ~Generator() { if (handle) handle.destroy(); } bool next() { handle.resume(); return !handle.done(); } T value() { return handle.promise().current_value; } }; Generator<int> fibonacci() { int a = 0, b = 1; while (true) { co_yield a; int temp = a + b; a = b; b = temp; } } // 使用 auto gen = fibonacci(); for (int i = 0; i < 10; ++i) { gen.next(); std::cout << gen.value() << " "; }

模块(Modules):

cpp
// math.ixx (模块接口) export module math; export int add(int a, int b) { return a + b; } export double multiply(double a, double b) { return a * b; } // main.cpp import math; int main() { int result = add(10, 20); return 0; }

std::format:

cpp
#include <format> std::string name = "Alice"; int age = 30; // 格式化字符串 std::string message = std::format("Name: {}, Age: {}", name, age); // 带格式的数字 double pi = 3.14159; std::string formatted = std::format("Pi: {:.2f}", pi); // Pi: 3.14 // 填充和对齐 std::string padded = std::format("{:>10}", "Hello"); // " Hello"

最佳实践

1. 优先使用 auto 进行类型推导

cpp
// 推荐 auto it = vec.begin(); auto result = std::make_unique<int>(42); // 不推荐 std::vector<int>::iterator it = vec.begin(); std::unique_ptr<int> result(new int(42));

2. 使用智能指针管理资源

cpp
// 推荐 auto ptr = std::make_unique<Resource>(); // 不推荐 Resource* ptr = new Resource();

3. 使用 nullptr 代替 NULL

cpp
// 推荐 int* ptr = nullptr; // 不推荐 int* ptr = NULL;

4. 使用 constexpr 进行编译期计算

cpp
// 推荐 constexpr int size = 1024; // 不推荐 const int size = 1024;

5. 使用范围 for 循环

cpp
// 推荐 for (const auto& val : vec) { std::cout << val << std::endl; } // 不推荐 for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << std::endl; }
标签:C++