C++ Uniform Initialization

박동현·2021년 1월 13일
0

C++공부

목록 보기
3/6

Uniform Initialization

C++ 에서 함수호출과 객체 선언은 문법적으로 햇갈리는 부분이 있다.

class A {
 public:
  A() { std::cout << "A's ctor" << std::endl; }
};

int main() {
  A a(); 
}

출력 값 :

위의 출력 값은 공백입니다.
이유는 A의 생성자가 아닌 A를 리턴하는 a라는 함수를 선언한 것으로 해석하기 때문입니다. C++ 11부터 도입된 Uniform Initialization(유니폼 초기화)는 이러한 상황에서 유용하게 사용할 수 있습니다.

class A {
 public:
  A() { std::cout << "A's ctor" << std::endl; }
};

int main() {
  A a{}; 
}

출력값 : "A's ctor

Initializatier list

벡터나 std::array 등의 컨테이너에 다음과 같이 사용할 수 있다.

std::vector<int> vec = { 1, 2, 3, 4, 5};
std::array<int, 3> arr = { 0, 1, 2};
std::map<int, std::string> map = { {1, "one"}, {2, "two"} };

주의사항

  • { }를 활용한 생성자는 다른 생성자들보다 우선순위가 높다. 그리고 { } 를 활용한 생성자는 데이터 손실이 있는 변환을 수행하지 않는다.
    (ex. double -> int )
class A {
 public:
 A(int a, double b) { std::cout << "normal ctor " <<std::endl; }

 A(std::initializer_list<int> lst) 
 { std::cout << "initializer_list" << std::endl;}
};

int main() {
 A(1, 0.5); //OK
 A{1, 0.5}; //error
}

위 코드 실행시 다음과 같은 오류가 발생한다.

이유는 일반 생성자보다 { }의 우선순위가 높기 때문에 initializer_list를 사용하려하는데 double->int 처럼 손실이 생기는 경우를 허용하지 않는다.

class A {
 public:
 A(int a, double b) { std::cout << "normal ctor " <<std::endl; }

 A(std::initializer_list<std::string> lst) 
 { std::cout << "initializer_list" << std::endl;}
};

int main() {
 A(1, 0.5); //OK
 A{1, 0.5}; //OK
}

위의 경우는 int -> string 처럼 타입 변환자체가 아예 불가능한 경우라 가능하다.

  • auto를 통해 문자열을 다룰 때 타입에 주의 해야한다
auto a = {"a","b","c"}; // a는 initializer_list<const char*>
auto b = {"a"s, "b"s, "c"s }; b는 initializer_list<std::string> 

리터럴 연산자를 통해 해결할 수 있다.

profile
엔진 프로그래머를 목표로합니다.

0개의 댓글