2009-12-08 3 views
12

새로운 구문 대신 () 이전의 구문을 사용할시기를 결정하는 경험이 있습니까 {}? {} 대신()을 사용할 C++ 0x의 통일 초기화?

이 구조체 초기화하려면 : 예를 들어 vector의 경우 지금

struct myclass 
{ 
    myclass(int px, int py) : x(px), y(py) {} 
private: 
    int x, y; 
}; 
... 
myclass object{0, 0}; 

를, 많은 생성자가 있습니다. 다음 작업을 수행 할 때마다 : 생성자 중 하나이기 때문에

vector<double> numbers{10}; 

나는 10 요소가 1 요소의 벡터 대신 하나를 얻을 :

explicit vector (size_type n, const T& value= T(), const Allocator& = Allocator()); 

내 의심 할 때마다하는 것입니다 벡터의 경우와 마찬가지로 initializer list 생성자를 정의하면 {} 구문과 함께 호출됩니다.

그래서 내가 옳다고 생각하는 것입니다. 즉 클래스가 초기화 생성자 목록 생성자를 정의하여 다른 생성자를 호출 할 때만 이전 구문으로 되돌려 야합니까? 예 :

vector<double> numbers(10); // 10 elements instead of just one element with value=10 
+6

초기화 프로그램 목록 생성자를 추가 할 때 클래스 클라이언트를 손상시킬 수 있습니까? 아야. –

+2

아니요, 이니셜 라이저 생성자는 AFAIK 위치의 다른 생성자에 영향을주지 않습니다. –

+1

@dribeas : 확실한가요? 클래스가 처음에 단일 int 인수를 취하는 생성자를 가지고 있고 새로운 구문으로 인스턴스를 생성한다고 가정 해 보겠습니다. 'initializer_list '을 사용하는 새로운 생성자가 추가되면, 이제 모든 객체가 추가 된 생성자를 사용하지 않을까요? 그물에있는 예제가 시대에 뒤떨어져 있고 목록에있는 벡터를 선언하는 것이 실제로 벡터 v {{2, 1}}와 같이 보이지 않는 한, 어디에서나 대괄호가 보이지 않습니다. – UncleBens

답변

2

가 이것 좀보세요 :

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=453&rll=1

변수에 {} 스타일 이니셜 라이저의 사용은 어떤 생성자의 초기화 목록에 직접 매핑이 없습니다 위의 코드를 수정하는 수업의 이러한 생성자 초기화 목록은 기존 호출자를 손상시키지 않고 추가/제거/수정할 수 있습니다.

기본적으로 컨테이너의 다른 동작은 특수하며 해당 컨테이너에 특수 코드가 필요합니다. 특히 생성자는 std::initializer_list입니다. POD 및 간단한 개체의 경우 {}()을 혼용하여 사용할 수 있습니다.

+0

"POD 및 간단한 개체의 경우 {}와()를 서로 바꿔서 사용할 수 있습니다." 아니요,'()'은 (생성자를 제외하고) 객체가 POD가되지 못하게하는 생성자가있는 경우에만 작동합니다. '{}'는 여전히 작동합니다. – Potatoswatter

9

표준 문서 (latest draft)에서 답변을 찾았습니다. 바라기를, 나는 내가 이해 한 것을 설명하려고 노력할 것이다.

클래스가 초기화리스트 생성자를 정의하는 경우마다 적절한 우선, 다음이 사용된다 : (203 페이지)

이니셜리스트 생성자 을 통해 선호

§ 8.5.4 목록 초기화 (13.3.1.7)에있는 다른 생성자.

나는이

어쨌든 비 균일 스타일 :)과 관련된 두통을 제거해야하는 중대한 기능, 생각, (내 질문에 대한 것입니다) 유일한 잡았다는 당신의 경우 이니셜 라이저 생성자가없는 클래스를 디자인하면 나중에 추가하여 놀라운 결과를 얻을 수 있습니다.

기본적으로 초기화 목록 생성자가 없었 std::vector 상상, 그 다음은 10 개 요소와 벡터를 만들 것입니다 :

std::vector<int> numbers{10}; 

를 초기화 목록 생성자를 추가함으로써, 컴파일러는 다른 이상을 선호하는 것 생성자는 {} 구문 때문입니다. init-list 생성자를 사용하여 init-list {10}의 요소가으로 허용되기 때문에이 문제가 발생합니다. 허용되는 변환이없는 경우 다른 모든 생성자를 사용해야합니다. 예 :

std::vector<string> vec{10}; 
// a vector of 10 elements. 
// the usual constructor got used because "{0}" 
// is not accepted as an init-list of type string.