C++17 新特性

一、C++17 发布时间

C++17 标准正式发布时间为 2017年12月,ISO 标准编号为 ISO/IEC 14882:2017。

二、C++17 核心新特性

  1. 结构化绑定 (Structured Bindings)
#include <tuple>
#include <map>

// 元组解包
auto [x, y, z] = std::make_tuple(1, 2.5, "hello");

// map 遍历
std::map<int, std::string> m = {{1, "one"}, {2, "two"}};
for (const auto& [key, value] : m) {
std::cout << key << ": " << value << '\n';
}

// 结构体成员绑定
struct Point { int x; int y; };
Point p{10, 20};
auto [px, py] = p;
  1. if/switch 初始化语句
// if 初始化
if (auto it = m.find(1); it != m.end()) {
std::cout << "Found: " << it->second << '\n';
}

// switch 初始化
switch (int n = rand() % 3; n) {
case 0: /*...*/ break;
case 1: /*...*/ break;
case 2: /*...*/ break;
}
  1. 内联变量 (Inline Variables)
// 头文件中定义内联变量(避免多重定义错误)
inline int global_counter = 0;

// 类静态成员初始化
class MyClass {
inline static int count = 0; // C++17 直接初始化
};
  1. 折叠表达式 (Fold Expressions)
template<typename... Args>
auto sum(Args... args) {
return (... + args); // 一元右折叠
}

template<typename... Args>
void print(Args... args) {
(std::cout << ... << args) << '\n'; // 二元左折叠
}

// 使用
int total = sum(1, 2, 3, 4, 5); // 15
print("Hello", " ", "World"); // Hello World
  1. std::optional
#include <optional>

std::optional<int> find(int key) {
if (key > 0) return key * 2;
return std::nullopt; // 无值
}

// 使用
if (auto val = find(5)) {
std::cout << *val << '\n'; // 10
}

// 提供默认值
int result = find(-1).value_or(0); // 0
  1. std::variant
#include <variant>
#include <string>

std::variant<int, double, std::string> v;
v = 42; // 存储 int
v = 3.14; // 存储 double
v = "hello"; // 存储 string

// 访问
std::visit([](auto&& arg) {
std::cout << arg << '\n';
}, v);
  1. std::any
#include <any>

std::any a = 42;
a = std::string("hello");

// 类型安全访问
try {
std::string s = std::any_cast<std::string>(a);
} catch (const std::bad_any_cast& e) {
std::cerr << e.what() << '\n';
}
  1. 文件系统库 (std::filesystem)
#include <filesystem>
namespace fs = std::filesystem;

// 遍历目录
for (auto& p : fs::directory_iterator(".")) {
std::cout << p.path() << '\n';
}

// 文件操作
if (fs::exists("test.txt")) {
auto size = fs::file_size("test.txt");
fs::rename("test.txt", "new.txt");
}
  1. 并行算法
#include <algorithm>
#include <execution>
#include <vector>

std::vector<int> v(1000000);

// 并行排序
std::sort(std::execution::par, v.begin(), v.end());

// 并行查找
auto it = std::find_if(std::execution::par,
v.begin(), v.end(),
[](int x) { return x > 100; });
  1. constexpr if (编译期 if)
template<typename T>
auto get_value(T t) {
if constexpr (std::is_pointer_v<T>) {
return *t; // 解引用指针
} else {
return t; // 直接返回值
}
}

// 使用
int x = 10;
int* p = &x;
auto v1 = get_value(x); // 10
auto v2 = get_value(p); // 10
  1. 类模板参数推导 (Class Template Argument Deduction)
std::pair p(1, 2.5); // 自动推导为 std::pair<int, double>
std::vector v{1, 2, 3}; // 自动推导为 std::vector<int>

// 自定义类推导指南
template<typename T>
struct MyContainer {
MyContainer(T t) : value(t) {}
T value;
};

// 推导指南
MyContainer(const char*) -> MyContainer<std::string>;

MyContainer c("hello"); // 推导为 MyContainer<std::string>
  1. std::string_view
#include <string_view>

void process(std::string_view sv) {
// 不拥有数据,避免拷贝
std::cout << sv.substr(0, 5) << '\n';
}

// 使用
process("Hello World"); // 不拷贝字符串
process(std::string("C++17")); // 从std::string转换
  1. 嵌套命名空间定义
// C++11/14 方式
namespace A {
namespace B {
namespace C {
/*...*/
}
}
}

// C++17 简化方式
namespace A::B::C {
/*...*/
}
  1. [[maybe_unused]] 属性
void foo(int x, [[maybe_unused]] int y) {
// 可能不使用参数y,避免编译器警告
std::cout << x << '\n';
}
  1. std::byte
#include <cstddef>

std::byte b{0x7F};
std::byte mask{0xF0};
auto result = b & mask; // 位操作

三、C++17 重要改进总结

类别主要特性
语法增强结构化绑定、if/switch初始化、折叠表达式、constexpr if
类型系统std::optional、std::variant、std::any、std::string_view
库扩展文件系统、并行算法、std::byte、数学特殊函数
模板改进类模板参数推导、auto非类型模板参数
其他内联变量、嵌套命名空间、属性增强
滚动至顶部