C++17 新特性簡解
一、核心語言特性
1. 結構化綁定(Structured Bindings)
用途:解構復合類型(如元組、結構體)為獨立變量
示例:
#include <iostream>
#include <tuple>int main() {// 解構 std::pairstd::pair<int, double> p{42, 3.14};auto [x, y] = p;std::cout << "Pair: " << x << ", " << y << "\n";// 解構結構體struct Point { int a; int b; };Point pt{10, 20};auto& [a, b] = pt; // 引用綁定a = 100;std::cout << "Point: " << pt.a << ", " << pt.b << "\n";return 0;
}
2. if/switch 初始化語句
用途:在條件語句中聲明臨時變量,限制作用域
示例:
#include <iostream>
#include <vector>int getValue() { return 42; }int main() {std::vector<int> vec{1, 2, 3};// if 初始化if (auto it = std::find(vec.begin(), vec.end(), 2); it != vec.end()) {std::cout << "Found: " << *it << "\n";}// switch 初始化switch (int key = getValue(); key) {case 42: std::cout << "Answer\n"; break;default: break;}return 0;
}
3. 內聯變量(Inline Variables)
用途:允許頭文件中直接定義全局變量
示例:
// header.h
inline int globalCount = 0; // 多文件包含安全struct MyClass {inline static int instanceCount = 0; // 類內初始化靜態成員
};// main.cpp
#include <iostream>
#include "header.h"int main() {MyClass::instanceCount++;std::cout << "Global: " << globalCount << ", Instance: " << MyClass::instanceCount << "\n";return 0;
}
4. 折疊表達式(Fold Expressions)
用途:簡化可變參數模板展開
示例:
#include <iostream>template<typename... Args>
auto sum(Args... args) {return (args + ...); // 折疊求和
}int main() {std::cout << "Sum: " << sum(1, 2, 3, 4) << "\n"; // 輸出 10return 0;
}
5. 類模板參數推導(CTAD)
用途:自動推導模板參數類型
示例:
#include <vector>
#include <tuple>int main() {std::pair p{1, "hello"}; // 推導為 pair<int, const char*>std::vector v{1, 2, 3}; // 推導為 vector<int>std::tuple t{4, 3.14, "π"}; // 推導為 tuple<int, double, const char*>return 0;
}
6. constexpr 擴展
用途:支持更多編譯期計算
示例:
#include <iostream>constexpr int factorial(int n) {if (n <= 1) return 1;return n * factorial(n - 1);
}int main() {constexpr int val = factorial(5);static_assert(val == 120); // 編譯期驗證std::cout << "5! = " << val << "\n";return 0;
}
二、標準庫增強
1. 文件系統庫(Filesystem)
頭文件:<filesystem>
示例:
#include <iostream>
#include <filesystem>namespace fs = std::filesystem;int main() {fs::path p = fs::current_path() / "test.txt";if (fs::exists(p)) {std::cout << "文件大小: " << fs::file_size(p) << "字節\n";}return 0;
}
2. 新容器類型
類型 | 用途 | 示例代碼 |
---|---|---|
std::optional<T> | 表示可能不存在的值 | [見下方] |
std::variant<T...> | 類型安全的聯合體 | [見下方] |
std::any | 存儲任意類型 | [見下方] |
std::string_view | 非擁有字符串視圖 | [見下方] |
完整示例:
#include <iostream>
#include <optional>
#include <variant>
#include <any>
#include <string_view>int main() {// optionalstd::optional<int> opt = 42;if (opt) std::cout << "Optional: " << *opt << "\n";// variantstd::variant<int, std::string> v = "hello";std::cout << "Variant: " << std::get<std::string>(v) << "\n";// anystd::any a = 3.14;if (a.type() == typeid(double)) {std::cout << "Any: " << std::any_cast<double>(a) << "\n";}// string_viewstd::string_view sv = "Hello World";std::cout << "View: " << sv.substr(0, 5) << "\n";return 0;
}
3. 并行算法
頭文件:<execution>
示例:
#include <iostream>
#include <vector>
#include <algorithm>
#include <execution>int main() {std::vector<int> data{5, 3, 1, 4, 2};// 并行排序std::sort(std::execution::par, data.begin(), data.end());// 并行遍歷std::for_each(std::execution::par, data.begin(), data.end(), [](int x) {std::cout << x << " ";});return 0;
}
三、其他改進
1. 嵌套命名空間簡化
namespace A::B::C { // 等價于 namespace A { namespace B { namespace C {class MyClass {};
}}int main() {A::B::C::MyClass obj;return 0;
}
2. 強制復制省略
struct NonCopyable {NonCopyable() = default;NonCopyable(const NonCopyable&) = delete;
};NonCopyable create() {return NonCopyable{}; // C++17 必須省略拷貝
}int main() {NonCopyable obj = create();return 0;
}
3. 新增屬性
[[nodiscard]] int critical() { return 42; }int main() {critical(); // 警告:返回值未使用return 0;
}
四、完整可編譯代碼示例
#include <iostream>
#include <tuple>
#include <vector>
#include <filesystem>
#include <optional>
#include <algorithm>
#include <execution>// 結構化綁定
void demo_structured_binding() {auto [x, y] = std::make_tuple(42, 3.14);std::cout << "Tuple: " << x << ", " << y << "\n";
}// 文件系統
void demo_filesystem() {namespace fs = std::filesystem;fs::path p = fs::current_path();std::cout << "當前路徑: " << p << "\n";
}// 并行算法
void demo_parallel() {std::vector<int> data{5, 3, 1, 4, 2};std::sort(std::execution::par, data.begin(), data.end());for (int n : data) std::cout << n << " ";
}int main() {demo_structured_binding();demo_filesystem();demo_parallel();return 0;
}
五、編譯與運行
- 編譯命令:
g++ -std=c++17 -o cpp17_demo cpp17_demo.cpp -lstdc++fs