5

STL 컨테이너가 빈 이니셜 라이저 목록이있는 대입 연산자를 처리하는 방법을 설명 할 수 있습니까?할당 연산자가 빈 inizializer_list에 있음

나는 같은 것을 할 것입니다 때 다른 한편으로

vector& operator= (vector&& x); 

:

vector<int> v; 
v = { }; 

호출되는 함수입니다 하지 :

vector& operator= (initializer_list<value_type> il); 

하지만를 , 내 자신의 수업과 비슷한 것을 할 때 :

struct A { 
    A& operator= (const A&) { return *this; } 
    A& operator= (A&&) { return *this; } 
    A& operator= (initializer_list<int>) { return *this; } 
}; 

/* ... */ 

A a; 
a = { }; 

코드는 VS2013에서 컴파일하고 말한다하지 않습니다 목록이 비어 있지

error C2593: 'operator =' is ambiguous 

경우, 잘 작동, 그냥 초기화 목록과 함수를 호출합니다. 문제는 목록이 비어있을 때만 나타납니다. 벡터에서 rvalue 할당 연산자를 호출합니다. 클래스에 오류가 발생합니다.

이 상황이 벡터 및 다른 컨테이너에서 어떻게 처리됩니까?

+1

어느'gcc'도'clang'는이 같은 오류 :

업데이트

이 관련된 두 개의 활성 버그가있는 것 같은데 그러나 [vs] (http://rextester.com/ZWD57818)의 오류를 확인했습니다. –

+0

[재생할 수 없습니다] (http://coliru.stacked-crooked.com/a/cd78ac29f69fdc05). – Shoe

+0

g ++와 clang ++는'operator ='의 오버로드 인 initializer_List 을 모호하지 않게 선택합니다. 나는 이것이 정확하다고 생각한다 : [over.ics.list]에 따르면,이 오버로드의 변환 등급은 완전 일치해야한다. 참조 오버로드의 경우 임시 (임시)가 만들어 져야하므로 참조 (아마도)는 직접 바인딩되지 않습니다. 따라서 변환 순서는 사용자 정의 변환입니다. (여기에 [over.ics.ref]가 정의되어 있고 list-init은 언급되어 있지 않다는 점을 참고하십시오.) – dyp

답변

3

이 버그 그 소리 (see it live) 및 GCC (see it live)을 표준 : initializer_list 과부하가이 정확히 일치 때문에 올바른 보이는이 프로그램을 수용하고 선택 것으로 보인다,이입니다

void f(std::initializer_list<int>); 
f({1,2,3}); // OK: f(initializer_list<int>) identity conversion 
f({’a’,’b’}); // OK: f(initializer_list<int>) integral promotion 
f({1.0}); // error: narrowing 
,691,363 :이 예에서 섹션 C++ draft standard13.3.3.1.5 리스트 초기화 시퀀스 2 항 에 덮여210

신원 전환정확히 일치입니다. 우리는 제 가 말한다 이동 기준 과부하

(강조 광산 앞으로 예정) : 매개 변수가 참조 인 경우

그렇지 않으면, 13.3.3.1.4을 참조하십시오. [참고 : 이 섹션의 규칙은 참조에 대한 기본 임시를 초기화하는 데 적용됩니다. -end note]

은 임시로 생성 된 것을 나타내며 그 결과 임시로 규칙을 적용 할 수 있습니다. 이는 사용자 정의 변환이며 일치 검색보다 나쁩니다.

이렇게 모호하지 않아야합니다.

+0

나는 귀하의 결론에 동의하지만 (OP에 대한 의견에서 논의 된 바와 같이) 13.3.3.1.4와 8.5.3 어느 쪽도 그것이 직접적으로 또는 간접적으로 구속력이 있는지를 알기 위해 적용 할 수 없다고 생각합니다 (그들은 인수 표현에 대해 이야기합니다). 오히려, 13.3.3.1.5/6 (참조에 관한 것)에있는 메모는 임시가 '{}'(8.5.4를 통해, 13.3.3.1에 따라 UDC로 평가 됨)에서 생성되었음을 나타냅니다. 5/5), 그리고 나서 직접적으로 바인딩된다 (8.5.3 "이니셜 라이저 표현이 클래스 프라임"인 경우, 13.3.3.1.4/1에 따라 정확히 일치로 평가됨). 13.3.3.1.1/3을 참조하십시오. – dyp

+0

@dyp 여러분이 의미하는 바를 봅니다. 여러분이 '13.3.3.1.5/5'에있는 메모를 의미한다고 생각합니다. * 참고 :이 섹션의 규칙은 참조 용 임시 임시. -end note *. –

+0

넘버링은 사용하고있는 초안에 달려 있습니다;) 최근 github repo에서 그들은'initializer_list'와 배열 부분을 두 단락으로 나눕니다. – dyp