[c++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects...

16
Effective Modern C++ Study C++ Korea 발표자 : 윤석준

Upload: seok-joon-yun

Post on 16-Jul-2015

281 views

Category:

Software


0 download

TRANSCRIPT

Page 1: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준

Effective Modern C++ Study C++ Korea

발표자 : 윤석준

Page 2: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준
Page 3: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준
Page 4: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준

Effective Modern C++ Study C++ Korea

Object 초기화할 때 아래와 같이 할 수 있다.

int x(0); // initializer is in parentheses

int y = 0; // initializer follows "="

int z{0}; // initializer is in braces

그리고 많은 경우 = 와 {}를 같이 쓰는 것도 가능하다.

int z = { 0 }; // initializer is in braces

4

http://egloos.zum.com/himskim/v/4049007

Page 5: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준

Effective Modern C++ Study C++ Korea

C++ 초보자들에게 = 는 공간을 할당하는 명령어로 오해되기 쉽지만, 사실은 그렇지 않다.

Widget w1; // call default constructor

Widget w2 = w1; // not an assignment; calls copy ctor

w1 = w2; // an assignment; calls copy operator =

5

Page 6: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준

Effective Modern C++ Study C++ Korea

non-static value에 대한

default 초기값을 설정하는데

( )는 안된다.

6

class Widget

{

private:

int x{0}; // fine. x's default value is 0

int y = 0; // also fine

int z(0); // error!

};

std::atomic<int> ai1{0}; // fine

std::atomic<int> ai2(0); // fine

std::atomic<int> ai3 = 0; // error!

copy가 안되는 object에 대해서는

()는 되는데, =는 안된다.

둘 다 가능한건 { } 뿐이다.

Page 7: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준

Effective Modern C++ Study C++ Korea 7

- 모든 상황에 다 사용이 가능하다.

+ 기존에 불가능 했던 것을 쉽게 사용할 수 있게 해 주었다.

std::vector<int> v{ 1, 3, 5 }; // v's initial content is 1, 3, 5

Page 8: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준
Page 9: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준

Effective Modern C++ Study C++ Korea 9

{ }를 이용한 생성자는 가능한 무조건 std::initializer_list 생성자를 호출한다.

(더 적합한 생성자가 있음에도 불구하고…)

class Widget

{

public:

Widget(int i, bool b);

Widget(int i, double d);

Widget(std::initializer_list<long double> il);

...

};

Widget w2{ 10, true }; // 10 and true convert to long double

Widget w4{ 10, 5.0 }; // 10 and 5.0 convert to long double

Page 10: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준

Effective Modern C++ Study C++ Korea 10

단, Casting이 불가능한 경우는 포기하더라.

class Widget {

public:

Widget(int i, bool b);

Widget(int i, double d);

Widget(std::initializer_list<std::string> il); // std::string로 바꿈

...

};

Widget w1(10, true); // use parens, still calls first ctor

Widget w2{10, true}; // use braces, now calls first ctor

Widget w3(10, 5.0); // use parens, still calls second ctor

Widget w4{10, 5.0}; // use braces, now calls second ctor

Page 11: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준

Effective Modern C++ Study C++ Korea 11

1. Narrowing conversion 방지

class Widget {

public:

Widget(std::initializer_list<bool> il);

...

};

Widget w{10, 5.0}; // error! invalid narrowing conversion from 'double' to 'bool'

Page 13: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준

Effective Modern C++ Study C++ Korea 13

( ) 초기화 와 { } 초기화가 다르게 동작한다면 ???

std::vector<int> v2(10, 20); // use non-std::initializer_list ctor

// create 10-element, all elements have value of 20

std::vector<int> v2{10, 20}; // use std::initializer_list ctor

// create 2-element, element values are 10 and 20

Page 14: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준

Effective Modern C++ Study C++ Korea 14

template 내부에서 객체를 생성하는 경우 ??? template<typename T, // type of object to create

typename... Ts> // type of arguments to use

void doSomeWork(Ts&&... params)

{

create local T object from params...

}

T localObject(std::forware<Ts>(params)...); T localObject{std::forward<Ts>(params)...};

std::vector<int> v;

...

doSomeWork<std::vector<int>>(10, 20);

Page 15: [C++ korea] effective modern c++ study item 7 distinguish between () and {} when creating objects +윤석준

Effective Modern C++ Study C++ Korea 15

• { } 초기화는 가장 널리 사용가능한 초기화이며, narrowing conversion과 most vexing parse를 막아준다.

• 생성자들 중에서 {} 초기화는 더 완벽해보이는 다른 생성자가 있음에도 불구하고

불가능한 경우를 제외하고는 std::initializer_list를 호출하고자 한다.

• ( ) 와 { } 중 뭐를 선택하느냐에 따라 다른 결과가 생성되는 예로는

std::vector<numeric type>을 2개의 인자로 생성하는 경우가 있다.

• template내에서 객체 생성시 ( )와 { } 중 뭐를 선택하냐는 것은 심사숙고 해야 한다.