對於C++17特性的文章已經有很多了,歸納自己的想法寫成幾篇文章
if / switch init
覺得很有用的特性之一
在沒有C++17之前,程式碼大概長這樣
1 2 3 4 5 6 7 8
| void test() { Foo *ptr = get_foo(); if (!ptr) do_something(); else ptr->do_something(); more_code(); }
|
在C++17之後
1 2 3 4 5 6 7
| void test() { if (Foo *ptr = get_foo(); !ptr) do_something(); else ptr->do_something(); more_code(); }
|
Structure Binding
在沒有Structure Binding時,程式碼大概長這樣
1 2 3 4
| std::tuple<int, double> stuff(); auto tup = stuff(); int i = std::get<0>(tup); double d = std::get<1>(tup);
|
或者是
1 2 3
| int i; double d; std::tie(i, d) = tup;
|
不過都比不上
傳統的
1
| errcode doSomething(obj *out_value);
|
之後會變成
1 2
| std::tuple<obj, errcode> doSomething(); auto [obj, err] = doSomething();
|
有點golang的感覺
不過看看以下程式碼
1 2 3 4 5 6 7 8 9 10 11
| struct Foo { int x = 0; std::string str = "world"; ~Foo() { std::cout << str << "\n"; } }; { auto [x, s] = Foo(); std::cout << "Hello "; s = "Goodbye"; }
|
結果出乎意料,不是大家所想的copy by value,而是copy by reference
Compiler大概做的是像這樣
1 2 3 4 5 6
| int main() { auto temp = Foo(); std::cout << "Hello "; temp.str = "Goodbye"; }
|
還有下面這個範例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| struct X { int i = 0; }; X makeX(); int main() {
X x;
auto [ b ] = makeX(); b++; auto const [ c ] = makeX(); c++; auto & [ d ] = makeX(); d++; auto & [ e ] = x; e++; auto const & [ f ] = makeX(); f++; }
|
– c++
編譯不過,因為這是bind to const reference
– auto & [d] = makeX()
編譯不過,因為left reference不能bind to right value
– f++
編譯不過,理由同第一條
Reference
— cpp17_in_TTs