auto
auto의 장점 : 변수 초기화 누락을 방지하고 장황한 변수 선언을 피하는 것
중괄호 초기화
의도와는 달리 함수를 선언하게 된 경험이 있다면 바로 이 부작용에 당한 것이다. 문제의 근원은 이렇다. 다음은 흔히 인수를 지정해서 생성자를 호출 하는 코드의 예이다.
Widget w1(10); // 인수 10으로 Widget의 생성자를 호출
그런데 이와 거의 비슷한 구문을 이용해서 인수 없이 Widget 의 생성자
class Widget { public:
Widget(); // 기본 생성자
Widget(std::initializer_list<int> il); // std::initializer // _list 생성자
… // 암묵적 변환 }; // 함수 없음
Widget w1; // 기본 생성자를 호출
Widget w2{}; // 역시 기본 생성자를 호출
Widget w3(); // 가장 성가신 구문 해석! 함수 선언임!
Widget w4({}); // std::initializer_list 생성자를 // 빈 초기치 목록으로 호출
Widget w5{{}}; // 마찬가지
를 호출하려 하면, 사실은 객체가 아니라 함수를 선언하게 된다.
Widget w2(); // 가장 성가신 구문 해석! Widget을 돌려주는, w2라는 이름의 함수를 선언한다
그러나 매개변수 목록을 중괄호로 감싸서 함수를 선언할 수는 없으므로, 중괄호를 이용해서 객체를 기본 생성할 때에는 이런 문제를 겪지 않는다.
Widget w3{}; //인수 없이 Widget의 생성자를 호출
중괄호 초기치를 std::initializer_list 를 받는 생성자에 대응시키고자 하는 컴파일러의 결심은 너무나 강해서, 심지어는 std::initializer_list 생성자가 가능한 최선의 부합인 경우에도 그 생성자를 호출할 수 없는 기현상이 생기기도 한다. 다음 예를 보자.
class Widget {
public:
Widget(int i, bool b); // 이전과 동일 Widget(int i, double d); // 이전과 동일
Widget(std::initializer_list<bool> il); // 이제는 요소의 // 형식이 bool
…
}; //암묵적 변환 함수는 없음
Widget w{10, 5.0}; // 오류! 좁히기 변환이 필요함
빈 중괄호 쌍은 빈 std::initializer_list 가 아니라 인수 없음을 뜻한다.
class Widget { public:
Widget(); // 기본 생성자
Widget(std::initializer_list<int> il); // std::initializer // _list 생성자
…
}; //암묵적 변환 함수 없음
Widget w1; // 기본 생성자를 호출
Widget w2{}; // 역시 기본 생성자를 호출
Widget w3(); // 가장 성가신 구문 해석! 함수 선언임!
Widget w4({}); // std::initializer_list 생성자를 빈 초기치 목록으로 호출
Widget w5{{}}; // 마찬가지
빈 std::initializer_list 로 std::initializer_list 생성자를 호출하고 싶다면 , 다음처럼 빈 중괄호 쌍을 괄호로 감싸거나 빈 중괄호 쌍을 또 다른 중괄호 쌍으로 감싸면 된다.
'C++ > Effective Modern' 카테고리의 다른 글
우측값(rvalue)에 대하여 (0) | 2024.06.07 |
---|---|
[C++] 형식 연역 규칙 (0) | 2022.07.05 |