4. 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
5. 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
6. 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에 대해서는
()는 되는데, =는 안된다.
둘 다 가능한건 { } 뿐이다.
7. Effective Modern C++ Study
C++ Korea7
- 모든 상황에 다 사용이 가능하다.
+ 기존에 불가능 했던 것을 쉽게 사용할 수 있게 해 주었다.
std::vector<int> v{ 1, 3, 5 }; // v's initial content is 1, 3, 5
8.
9. Effective Modern C++ Study
C++ Korea9
{ }를 이용한 생성자는 가능한 무조건 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
10. Effective Modern C++ Study
C++ Korea10
단, 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
11. Effective Modern C++ Study
C++ Korea11
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'
12. Effective Modern C++ Study
C++ Korea12
2. 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
13. Effective Modern C++ Study
C++ Korea13
( ) 초기화 와 { } 초기화가 다르게 동작한다면 ???
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
14. Effective Modern C++ Study
C++ Korea14
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);
15. Effective Modern C++ Study
C++ Korea15
• { } 초기화는 가장 널리 사용가능한 초기화이며, narrowing conversion과 most vexing parse를 막아준다.
• 생성자들 중에서 {} 초기화는 더 완벽해보이는 다른 생성자가 있음에도 불구하고
불가능한 경우를 제외하고는 std::initializer_list를 호출하고자 한다.
• ( ) 와 { } 중 뭐를 선택하느냐에 따라 다른 결과가 생성되는 예로는
std::vector<numeric type>을 2개의 인자로 생성하는 경우가 있다.
• template내에서 객체 생성시 ( )와 { } 중 뭐를 선택하냐는 것은 심사숙고 해야 한다.