20
Effective Modern C++ Study C++ Korea Speaker : Yun Seok-joon ( [email protected] )

[C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Embed Size (px)

Citation preview

Page 1: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea

Speaker : Yun Seok-joon ( [email protected] )

Page 2: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준
Page 3: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

1. Object Initializing

2. Uniform Initializer

3. std::initializer_list생성자

4. template 내부에서 object 생성

Page 4: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준
Page 5: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ 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

5

Object 초기화에는 COPY 불가 Object에대해서는

중괄호 { } , 괄호 ( ) , 대입 = 가있습니다.

통상적으로 = { } 는중괄호 { } 와동일하게취급됩니다만… 다르게취급하자는표준안 N3922가통과되었습니다.

자세한내용은김명신부장님 Blog 에관련글이있습니다.

김명신의즐거운하루 - C++11 auto 와 {}-init-list의모호함 : http://egloos.zum.com/himskim/v/4049007

Page 6: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea

non-static value에대한 default 초기값을설정하는데

중괄호 { } , 대입 = 는 OK

괄호 ( ) 는 Error

6

class Widget

{

private:

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

int y = 0; // also fine

int z(0); // error!

};

Page 7: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea7

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

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

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

COPY 불가 Object에대해서는

중괄호 { } , 괄호 ( ) 는 OK

대입 = 은 Error

Page 8: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea8

중괄호 { }

Uniform Initializer

Page 9: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준
Page 10: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea10

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

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

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

Page 11: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea11

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 12: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea12

• Most vexing parse 방지

class Widget {

public:

Widget();

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

...

};

Widget w1; // calls default ctor

Widget w2{}; // also calls default ctor

Widget w3(); // most vexing parse! declares a function!

http://devluna.blogspot.kr/2015/01/item-6-c-most-vexing-parse.html

Page 13: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준
Page 14: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea

std::initializer_list

14

- 생성자의인자로 std::initializer_list 를받는것

- 없다면개체초기화에괄호 ( ) 와중괄호 { }가같은의미

- 있다면중괄호 { } 를이용한초기화는 std::initializer_list 를호출

class Widget

{

public:

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

...

};

Page 15: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea

std::initializer_list

15

중괄호 { }를이용한초기화는무조건 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 16: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea

std::initializer_list

16

단, 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 17: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준
Page 18: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea18

괄호 ( ) 초기화 , 중괄호 { } 초기화가다르다면 ?

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 19: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea19

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 20: [C++ Korea] Effective Modern C++ mva item 7 distinguish between and {} when creating objects +윤석준

Effective Modern C++ StudyC++ Korea20

• 중괄호 { } 초기화는 모든 경우에 사용 가능한 초기화이며,

narrowing conversion과 most vexing parse를 막아줍니다.

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

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

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

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

• template내에서 객체 생성시 괄호 ( ) 와 중괄호 { } 중 뭐를 선택하냐는 것은 심사숙고 해야 합니다.http://devluna.blogspot.kr/2015/01/item-7-object.html

[email protected]