if constexpr
以往我們可能寫出類似這樣的程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <string> template <typename T> int func(T) { return -1; } template <> int func(std::string v) { return 12; } template <> int func(int) { return 34; } int main() { return func(std::string("123")); }
|
如今我們可以寫成這樣
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <string> template <typename T> int func(T) { if constexpr (std::is_same_v<T, std::string>) { return 12; } else if constexpr(std::is_same_v<T, int>) { return 34; } else { return -1; } } int main() { return func(std::string("123")); }
|
省去了很多的冗於
如果配合variant
來使用,程式碼可以寫成這樣
1 2 3 4 5 6 7 8 9 10 11 12
| #include <string> #include <variant> using unionType = std::variant<std::string, int>; int main() { unionType v = 3; return std::visit([](const auto &v) { using T = std::decay_t<decltype(v)>; if constexpr (std::is_same_v<T, int>) return 12; else return 34; }, v); }
|
Class Deduction guide
在c++17之前,寫了很多這樣子的程式碼
1 2
| std::mutex m; std::lock_guard<std::mutex> lock(m);
|
為什麼函數可以推導出型別,而類型不行,於是C++17放寬了這條件
1 2
| std::lock_guard lock(m); std::vector v{1, 2, 3};
|
當然,也是有explicit class deduction guide的,請參考reference
template <auto>
目前看起來沒什麼用的feature
未用c++17前程式碼長這樣
1 2 3 4 5
| template <typename T, T v> struct integral_constant { static constexpr T value = v; }; integral_constant<int, 1024>::value;
|
用了C++17後
1 2 3 4 5
| template <auto v> struct integral_constant { static constexpr auto value = v; }; integral_constant<1024>::value;
|
nested namespace
早該有的東西, 結果拖到這麼後面才加進來
1 2 3 4 5
| namespace X { namespace Y { struct Foo; } }
|
現在可以寫成
1 2 3
| namespace X::Y { struct Foo; }
|
Fold expression
以加法為範例
在c++17之前的寫法
1 2 3 4 5 6 7 8
| template<typename T> T sum(T v) { return v; } template<typename T, typename... Args> T sum(T first, Args... args) { return first + sum(args...); }
|
把sum寫成兩部分,雖然不是不行,不過總覺得被切割加重學習負擔
用上if constexpr
1 2 3 4 5 6 7 8
| template<typename T, typename... Args> T sum(T first, Args... args) { if constexpr (sizeof...(Args) == 0) { return first; } else { return first + sum(args...); } }
|
好一點了,用上Fold expression會變成怎樣
1 2 3 4
| template<typename ...Args> auto sum(Args&&... args) { return (args + ...); }
|
跟if constexpr
方法比是更精簡了一點,不過多了一堆語法規則,實在不太划算
Reference
— A Tour of C++ 17: If Constexpr
— C++17中的deduction guide
— C++17 Fold Expressions