2014-02-19 10 views
16

내가 본 코드 중 std::initializer_list을 사용하는 대부분의 C++ 11 코드는 가치가 있지만, 때로는 rvalue reference로 가져옵니다. 이 일을할만한 이유가 있습니까?rvalue reference 대 value의 std :: initializer_list를 사용하는 이유는 무엇입니까?

예를 들어, 내가 건너 온 적이 거의 모든 예는 다음을 수행합니다

class A { 
    public: 
    A(std::initializer_list<int>); 
}; 

하지만이 가끔 완료보고 계속 :

class B { 
    public: 
    B(std::initializer_list<int> &&); 
}; 

나는를 rvalue 참조의 사용과 목적을 이해 일반적으로이지만, std::initializer_list의 경우 다른 쪽보다 선호되는 이유는 무엇입니까? 내가 생각할 수있는 유일한 점은 class A이 이니셜 라이저 목록을 별도로 구성 할 수 있으며 class B이이를 방지한다는 것입니다.

std::initializer_list<int> values {1,2,3,4}; 
A a(values); // valid 
B b(values); // error 

그러나 나는 그것을 막는 것이 바람직한 일이 될 수있는 좋은 이유를 생각할 수 없습니다.

그래서 왜 값 대신에 우세 참조로 std::initializer_list을 가져갈 수 있습니까?

+1

글쎄, 아마도 누군가가 정말로 당신이 목록을 문자 그대로 전달하기를 원할지도 모릅니다. –

+0

좋은 질문입니다. 나 자신을 궁금해하고있었습니다. 그건 그렇고,'B b (std :: move (values));는 여전히 컴파일 될 것입니다. – iavr

+0

어쩌면 어쩌면 의문 스러울 지 모르지만 - 이것을 보았던 곳에서 rvalue 참조 버전을 구현하면 단서가 생깁니 까? – zmb

답변

7

나는 이 좋은 이유가 확실하지 않지만 코드 작성자는 이니셜 라이저 목록을 값으로 전달하면 목록에 불필요한 요소가 복사 될 수 있다고 생각할 것입니다. 물론 이것은 사실이 아닙니다. 이니셜 라이저 목록 복사는 기본 값을 복사하지 않습니다.

4

std::initializer_list은 값으로 전달되는 경우에도 참조 시맨틱을 구현하므로 참조로 전달하는 것은 잘못된 것입니다. (그것은 단지 비 소유 포인터를 포함합니다.)

이 아무것도에 결합 보편적 참조는하지만, 그들은 그래서 initializer_list 참조 방식이 점점의 보강-초기화 목록 구문 (예 : { x, y })에 의해 초기화 할 수 없습니다 상황의 조합을 취할 것입니다.