C++新特性概览
目录
C++11 新特性
1. auto 关键字
自动类型推导,让编译器根据初始化表达式推导变量类型。
#include <vector>
#include <map>
int main() {
// 基本类型推导
auto x = 42; // int
auto y = 3.14; // double
auto z = "hello"; // const char*
// 复杂类型推导
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it = vec.begin(); // std::vector<int>::iterator
std::map<std::string, int> m;
auto pair = std::make_pair("key", 100); // std::pair<const char*, int>
return 0;
}
2. Lambda 表达式
匿名函数,支持闭包和函数式编程。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
// 基本lambda
auto print = [](int x) { std::cout << x << " "; };
// 使用lambda进行遍历
std::for_each(numbers.begin(), numbers.end(), print);
std::cout << std::endl;
// 捕获外部变量
int multiplier = 2;
auto multiply = [multiplier](int x) { return x * multiplier; };
// 使用transform和lambda
std::vector<int> doubled(numbers.size());
std::transform(numbers.begin(), numbers.end(), doubled.begin(), multiply);
// 按引用捕获
int sum = 0;
std::for_each(numbers.begin(), numbers.end(), [&sum](int x) { sum += x; });
std::cout << "Sum: " << sum << std::endl;
return 0;
}
3. 智能指针
自动内存管理,避免内存泄漏。
#include <memory>
#include <iostream>
class Resource {
public:
Resource(int id) : id_(id) {
std::cout << "Resource " << id_ << " created" << std::endl;
}
~Resource() {
std::cout << "Resource " << id_ << " destroyed" << std::endl;
}
void use() {
std::cout << "Using resource " << id_ << std::endl;
}
private:
int id_;
};
int main() {
// unique_ptr - 独占所有权
{
std::unique_ptr<Resource> ptr1 = std::make_unique<Resource>(1);
ptr1->use();
// 转移所有权
std::unique_ptr<Resource> ptr2 = std::move(ptr1);
// ptr1 现在为空
if (!ptr1) {
std::cout << "ptr1 is empty" << std::endl;
}
ptr2->use();
} // ptr2 自动销毁,Resource 1 被删除
// shared_ptr - 共享所有权
{
std::shared_ptr<Resource> ptr1 = std::make_shared<Resource>(2);
std::cout << "Reference count: " << ptr1.use_count() << std::endl;
{
std::shared_ptr<Resource> ptr2 = ptr1;
std::cout << "Reference count: " << ptr1.use_count() << std::endl;
ptr2->use();
} // ptr2 销毁,引用计数减1
std::cout << "Reference count: " << ptr1.use_count() << std::endl;
} // ptr1 销毁,Resource 2 被删除
return 0;
}
4. 范围for循环
简化容器遍历语法。
#include <vector>
#include <map>
#include <iostream>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
// 基本范围for循环
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// 使用auto和引用
for (auto& num : numbers) {
num *= 2; // 修改原始值
}
// 遍历map
std::map<std::string, int> scores = {
{"Alice", 95},
{"Bob", 87},
{"Charlie", 92}
};
for (const auto& pair : scores) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
5. 初始化列表
统一的初始化语法。
#include <vector>
#include <map>
#include <iostream>
class Point {
public:
Point(int x, int y) : x_(x), y_(y) {}
void print() const {
std::cout << "(" << x_ << ", " << y_ << ")" << std::endl;
}
private:
int x_, y_;
};
int main() {
// 基本类型初始化
int x{42};
double y{3.14};
// 容器初始化
std::vector<int> numbers{1, 2, 3, 4, 5};
std::map<std::string, int> scores{
{"Alice", 95},
{"Bob", 87},
{"Charlie", 92}
};
// 对象初始化
Point p{10, 20};
p.print();
// 数组初始化
int arr[]{1, 2, 3, 4, 5};
return 0;
}
C++14 新特性
1. 泛型Lambda
Lambda参数可以使用auto。
#include <iostream>
#include <vector>
#include <string>
int main() {
// 泛型lambda
auto print = [](const auto& item) {
std::cout << item << " ";
};
// 可以用于不同类型
print(42);
print(3.14);
print(std::string("hello"));
std::cout << std::endl;
// 更复杂的泛型lambda
auto add = [](auto a, auto b) {
return a + b;
};
std::cout << add(1, 2) << std::endl; // int + int
std::cout << add(1.5, 2.5) << std::endl; // double + double
std::cout << add(std::string("Hello "), std::string("World")) << std::endl;
return 0;
}
2. 变量模板
允许模板化变量。
#include <iostream>
#include <type_traits>
// 变量模板
template<typename T>
constexpr T pi = T(3.1415926535897932385);
// 类型特征变量模板
template<typename T>
constexpr bool is_integral_v = std::is_integral<T>::value;
int main() {
// 使用不同类型的pi
std::cout << "float pi: " << pi<float> << std::endl;
std::cout << "double pi: " << pi<double> << std::endl;
// 使用类型特征
std::cout << "int is integral: " << is_integral_v<int> << std::endl;
std::cout << "float is integral: " << is_integral_v<float> << std::endl;
return 0;
}
3. 返回类型推导
函数返回类型可以使用auto推导。
#include <iostream>
// 简单返回类型推导
auto add(int a, int b) {
return a + b; // 推导为int
}
// 模板函数返回类型推导
template<typename T, typename U>
auto multiply(T a, U b) {
return a * b; // 推导为T和U运算的结果类型
}
// 递归函数需要显式指定返回类型或使用尾随返回类型
auto factorial(int n) -> int {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
int main() {
auto result1 = add(3, 4);
std::cout << "3 + 4 = " << result1 << std::endl;
auto result2 = multiply(3.5, 2);
std::cout << "3.5 * 2 = " << result2 << std::endl;
auto result3 = factorial(5);
std::cout << "5! = " << result3 << std::endl;
return 0;
}
C++17 新特性
1. 结构化绑定
将复合类型的成员绑定到变量。
#include <iostream>
#include <tuple>
#include <map>
#include <array>
std::tuple<int, double, std::string> getData() {
return {42, 3.14, "hello"};
}
int main() {
// 元组结构化绑定
auto [id, value, name] = getData();
std::cout << "ID: " << id << ", Value: " << value << ", Name: " << name << std::endl;
// pair结构化绑定
std::map<std::string, int> scores = {{"Alice", 95}, {"Bob", 87}};
for (const auto& [name, score] : scores) {
std::cout << name << ": " << score << std::endl;
}
// 数组结构化绑定
std::array<int, 3> arr = {1, 2, 3};
auto [a, b, c] = arr;
std::cout << "a=" << a << ", b=" << b << ", c=" << c << std::endl;
return 0;
}
2. if constexpr
编译时条件语句。
#include <iostream>
#include <type_traits>
template<typename T>
void process(T value) {
if constexpr (std::is_integral_v<T>) {
std::cout << "Processing integer: " << value << std::endl;
} else if constexpr (std::is_floating_point_v<T>) {
std::cout << "Processing float: " << value << std::endl;
} else {
std::cout << "Processing other type" << std::endl;
}
}
template<typename T>
auto getValue(T container) {
if constexpr (std::is_same_v<T, std::string>) {
return container.length();
} else {
return container.size();
}
}
int main() {
process(42); // 整数分支
process(3.14); // 浮点分支
process("hello"); // 其他类型分支
std::string str = "hello";
std::cout << "String length: " << getValue(str) << std::endl;
return 0;
}
3. std::optional
表示可能不存在的值。
#include <iostream>
#include <optional>
#include <string>
std::optional<int> divide(int a, int b) {
if (b == 0) {
return std::nullopt; // 返回空值
}
return a / b;
}
std::optional<std::string> findUser(int id) {
if (id == 1) {
return "Alice";
} else if (id == 2) {
return "Bob";
}
return std::nullopt;
}
int main() {
// 检查除法结果
auto result1 = divide(10, 2);
if (result1.has_value()) {
std::cout << "10 / 2 = " << result1.value() << std::endl;
}
auto result2 = divide(10, 0);
if (!result2) {
std::cout << "Division by zero!" << std::endl;
}
// 使用value_or提供默认值
auto user = findUser(3);
std::cout << "User: " << user.value_or("Unknown") << std::endl;
return 0;
}
4. std::variant
类型安全的联合体。
#include <iostream>
#include <variant>
#include <string>
int main() {
std::variant<int, double, std::string> var;
// 存储不同类型的值
var = 42;
std::cout << "Integer: " << std::get<int>(var) << std::endl;
var = 3.14;
std::cout << "Double: " << std::get<double>(var) << std::endl;
var = std::string("hello");
std::cout << "String: " << std::get<std::string>(var) << std::endl;
// 使用访问器
std::visit([](const auto& value) {
std::cout << "Current value: " << value << std::endl;
}, var);
// 检查当前类型
if (std::holds_alternative<std::string>(var)) {
std::cout << "Currently holds a string" << std::endl;
}
return 0;
}
C++20 新特性
1. 概念 (Concepts)
对模板参数进行约束。
#include <iostream>
#include <concepts>
#include <type_traits>
// 定义概念
template<typename T>
concept Numeric = std::is_arithmetic_v<T>;
template<typename T>
concept Printable = requires(T t) {
std::cout << t;
};
// 使用概念约束模板
template<Numeric T>
T add(T a, T b) {
return a + b;
}
template<typename T>
requires Printable<T>
void print(const T& value) {
std::cout << value << std::endl;
}
// 更复杂的概念
template<typename T>
concept Container = requires(T t) {
t.begin();
t.end();
t.size();
};
template<Container C>
void printContainer(const C& container) {
std::cout << "Container size: " << container.size() << std::endl;
for (const auto& item : container) {
std::cout << item << " ";
}
std::cout << std::endl;
}
int main() {
// 使用概念约束的函数
std::cout << add(3, 4) << std::endl;
std::cout << add(3.5, 2.1) << std::endl;
print(42);
print("Hello World");
std::vector<int> vec = {1, 2, 3, 4, 5};
printContainer(vec);
return 0;
}
2. 协程 (Coroutines)
支持异步编程和生成器。
#include <iostream>
#include <coroutine>
#include <exception>
// 简单的生成器协程
struct Generator {
struct promise_type {
int 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(int value) {
current_value = value;
return {};
}
void return_void() {}
void unhandled_exception() { std::terminate(); }
};
std::coroutine_handle<promise_type> coro;
Generator(std::coroutine_handle<promise_type> h) : coro(h) {}
~Generator() { if (coro) coro.destroy(); }
bool next() {
coro.resume();
return !coro.done();
}
int value() {
return coro.promise().current_value;
}
};
Generator fibonacci() {
int a = 0, b = 1;
while (true) {
co_yield a;
auto temp = a;
a = b;
b = temp + b;
}
}
int main() {
auto fib = fibonacci();
for (int i = 0; i < 10; ++i) {
if (fib.next()) {
std::cout << fib.value() << " ";
}
}
std::cout << std::endl;
return 0;
}
3. 模块 (Modules)
新的代码组织方式,替代头文件。
// math_module.cppm (模块接口文件)
export module math_utils;
export namespace math {
int add(int a, int b) {
return a + b;
}
int multiply(int a, int b) {
return a * b;
}
// 私有函数,不导出
int helper_function() {
return 42;
}
}
// main.cpp (使用模块)
import math_utils;
#include <iostream>
int main() {
std::cout << "2 + 3 = " << math::add(2, 3) << std::endl;
std::cout << "4 * 5 = " << math::multiply(4, 5) << std::endl;
// helper_function() 不可访问,因为没有导出
return 0;
}
4. 范围库 (Ranges)
函数式编程风格的算法库。
#include <iostream>
#include <vector>
#include <ranges>
#include <algorithm>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 使用ranges进行链式操作
auto result = numbers
| std::views::filter([](int n) { return n % 2 == 0; }) // 过滤偶数
| std::views::transform([](int n) { return n * n; }) // 平方
| std::views::take(3); // 取前3个
std::cout << "First 3 squares of even numbers: ";
for (int n : result) {
std::cout << n << " ";
}
std::cout << std::endl;
// 使用ranges算法
std::vector<std::string> words = {"hello", "world", "cpp", "ranges"};
// 排序
std::ranges::sort(words);
// 查找
auto it = std::ranges::find(words, "cpp");
if (it != words.end()) {
std::cout << "Found: " << *it << std::endl;
}
// 计数
auto count = std::ranges::count_if(words, [](const std::string& s) {
return s.length() > 3;
});
std::cout << "Words longer than 3 characters: " << count << std::endl;
return 0;
}
5. 三路比较运算符 (Spaceship Operator)
简化比较操作的实现。
#include <iostream>
#include <compare>
class Point {
public:
Point(int x, int y) : x_(x), y_(y) {}
// 自动生成所有比较运算符
auto operator<=>(const Point& other) const = default;
void print() const {
std::cout << "(" << x_ << ", " << y_ << ")";
}
private:
int x_, y_;
};
class Version {
public:
Version(int major, int minor, int patch)
: major_(major), minor_(minor), patch_(patch) {}
// 自定义三路比较
std::strong_ordering operator<=>(const Version& other) const {
if (auto cmp = major_ <=> other.major_; cmp != 0) return cmp;
if (auto cmp = minor_ <=> other.minor_; cmp != 0) return cmp;
return patch_ <=> other.patch_;
}
bool operator==(const Version& other) const = default;
void print() const {
std::cout << major_ << "." << minor_ << "." << patch_;
}
private:
int major_, minor_, patch_;
};
int main() {
Point p1(1, 2);
Point p2(3, 4);
Point p3(1, 2);
std::cout << "p1 == p3: " << (p1 == p3) << std::endl;
std::cout << "p1 < p2: " << (p1 < p2) << std::endl;
std::cout << "p1 <= p2: " << (p1 <= p2) << std::endl;
Version v1(1, 2, 3);
Version v2(1, 3, 0);
Version v3(2, 0, 0);
std::cout << "v1 < v2: " << (v1 < v2) << std::endl;
std::cout << "v2 < v3: " << (v2 < v3) << std::endl;
return 0;
}
总结
C++的现代特性大大提升了语言的表达能力和安全性:
- C++11: 引入了现代C++的基础特性,如auto、lambda、智能指针等
- C++14: 完善了C++11的特性,增加了泛型lambda和变量模板
- C++17: 带来了结构化绑定、if constexpr等实用特性
- C++20: 引入了概念、协程、模块等重大特性,使C++更加现代化
这些特性使得C++代码更加简洁、安全和高效,是现代C++开发的重要工具。
3775

被折叠的 条评论
为什么被折叠?



