2013-05-31 2 views
10

통일 초기화 구문 차이

A a{ A() }; 

과 일 사이의 차이점은 무엇입니까,

A a(A{}); 

Most Vexing Parse을 피하기 위해? 특정 제품을 사용해야하는시기는 언제입니까?

+2

이 특별한 상황에서 가장 간단한 옵션은'A a;'입니까? 맞습니까? 만약 내가 이것을 오해하지 않는다면, 당신이 제안하는 구문은 A의 생성자에 전달하고자하는 임시가'A'와는 다른 타입 인 경우에만 의미가 있습니다. 맞습니까? 나는. 'A {B()}; '. – jogojapan

답변

13

두 가지 구문은 대부분의 상황에서 동일하며 선택할 대상은 대부분 취향입니다. 당신이 균일 초기화를하는 경우, 내가 뭘 제안 :

A a{ A{} }; 

을 그렇지 않으면 혼자 명확하게 할 수 있습니다 괄호 : 한 상황 (매우 가능성이 있음을,

A a((A())); // This can't be parsed as a function declaration 

공지 사항, 내가 말을해야) 여기서 귀하의 질문에 표시된 두 양식은 동일하지 않습니다. 클래스 Ainitializer_list<A>를 사용하는 생성자가있는 경우 괄호를 사용하는 경우, 그 생성자는 복사 생성자를 통해 선호됩니다

#include <initializer_list> 
#include <iostream> 

struct A 
{ 
    A() { } 
    A(std::initializer_list<A> l) { std::cout << "init-list" << std::endl; } 
    A(A const& a) { std::cout << "copy-ctor" << std::endl; } 
}; 

int main() 
{ 
    A a(A{}); // Prints "copy-ctor" (or nothing, if copy elision is performed) 
    A b{A()}; // Prints "init-list" 
} 

위의 차이는이 live example에 표시됩니다.

+2

사실, 첫 번째 *는 "copy-ctor"를 인쇄하지 않습니다. 나는 그것의 복사 - elision 생각합니다. –

+0

@MemyselfandI : 허, 맞아요, 컴파일러가 복사본을 삭제하고 있습니다.하지만 개념적으로 복사 생성자가 선택되었습니다. –

+0

최적화가 활성화되었을 때만 복사 할 수 있습니까? –

9

대부분의 경우 그들은 동일하지만 A a{ A() };std::initializer_list 생성자가있는 경우이를 선호하며 A a(A{});은 이동/복사 생성자를 선호합니다.

생성자가 이동/복사 생성자를 호출하면 새로운 개체의 생성을 피할 수 있지만 std::initializer_list 생성자에서는 불가능합니다.

어느 구문도 함수 선언으로 파싱되지 않으므로 두 가지 모두 가장 난해한 구문 분석을 피할 수 있습니다.

#include <iostream> 
#include <initializer_list> 
struct A { 
    A() { 
     std::cout << "A()\n"; 
    } 
    A(A&&) { 
     std::cout << "A(A&&)\n"; 
    } 
    A(std::initializer_list<A>) { 
     std::cout << "A(std::initializer_list<A>)\n"; 
    } 
}; 
int main() 
{ 
    {A a{ A() };} // Prints "A()\n" "A(std::initializer_list<A>)\n" 
    {A a(A{});} // Prints "A()\n" and *possibly* 
        // (depending on copy elision) "A(A&&)\n" 
}