5. 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
5
Object 초기화에는 COPY 불가 Object에 대해서는
중괄호 { } , 괄호 ( ) , 대입 = 가 있습니다.
통상적으로 = { } 는 중괄호 { } 와 동일하게 취급됩니다만… 다르게 취급하자는 표준안 N3922가 통과되었습니다.
자세한 내용은 김명신 부장님 Blog 에 관련 글이 있습니다.
김명신의 즐거운 하루 - C++11 auto 와 {}-init-list의 모호함 : http://egloos.zum.com/himskim/v/4049007
6. Effective Modern C++ Study
C++ 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!
};
7. Effective Modern C++ Study
C++ Korea7
std::atomic<int> ai1{0}; // fine
std::atomic<int> ai2(0); // fine
std::atomic<int> ai3 = 0; // error!
COPY 불가 Object에 대해서는
중괄호 { } , 괄호 ( ) 는 OK
대입 = 은 Error
10. Effective Modern C++ Study
C++ Korea10
모든 상황에 다 사용이 가능하다.
+ 기존에 불가능 했던 것을 쉽게 사용할 수 있게 해 주었다.
std::vector<int> v{ 1, 3, 5 }; // v's initial content is 1, 3, 5
11. Effective Modern C++ Study
C++ 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'
12. Effective Modern C++ Study
C++ 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
14. Effective Modern C++ Study
C++ Korea
std::initializer_list
14
- 생성자의 인자로 std::initializer_list 를 받는 것
- 없다면 개체 초기화에 괄호 ( ) 와 중괄호 { }가 같은 의미
- 있다면 중괄호 { } 를 이용한 초기화는 std::initializer_list 를 호출
class Widget
{
public:
Widget(std::initializer_list<long double> il);
...
};
15. Effective Modern C++ Study
C++ 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
16. Effective Modern C++ Study
C++ 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
18. Effective Modern C++ Study
C++ 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
19. Effective Modern C++ Study
C++ 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);
20. Effective Modern C++ Study
C++ 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
icysword77@gmail.com