0%

Summary about C++17 Part 1

對於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
auto [i, d] = stuff();

傳統的

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