Appearance
高级特性
本章将介绍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++特性,可以编写更简洁、更安全、更高效的代码。
