이 코드를 고려하십시오.
#include <vector>
#include <iostream>
enum class A
{
X, Y
};
struct Test
{
Test(const std::vector<double>&, const std::vector<int>& = {}, A = A::X)
{ std::cout << "vector overload" << std::endl; }
Test(const std::vector<double>&, int, A = A::X)
{ std::cout << "int overload" << std::endl; }
};
int main()
{
std::vector<double> v;
Test t1(v);
Test t2(v, {}, A::X);
}
인쇄합니다 :
vector overload
int overload
모호한 과부하 해결로 인해 컴파일 오류가 발생하지 않는 이유는 무엇입니까? 두 번째 생성자가 제거되면 vector overload
두 번 얻 습니다. 메트릭 어떤 것은 의해 어떻게 / int
는 명확하게 더 나은 일치 {}
보다 더 std::vector<int>
?
생성자 서명은 확실히 더 잘릴 수는 있지만 동등한 코드 조각에 속아서이 질문에 중요한 것이 없어야합니다.
답변
이 글은 다음의 [over.ics.list] , 강조 광산
6 그렇지 않으면, 매개 변수가 집계되지 않은 클래스 X이고 [over.match.list]에 따른 과부하 해상도가 X의 단일 생성자 C를 선택하여 인수 이니셜 라이저 목록에서 X 유형의 오브젝트 초기화를 수행합니다.
C가 이니셜 라이저 목록 생성자 가 아니고 이니셜 라이저 목록에 cv U 유형 의 단일 요소가있는 경우 (여기서 U는 X 또는 X에서 파생 된 클래스 임) U가 X 인 경우 암시 적 변환 시퀀스는 Exact Match 순위이거나 U는 X에서 파생됩니다.
그렇지 않으면, 내재적 변환 시퀀스는 제 2 표준 변환 시퀀스와 동일성 변환을 갖는 사용자 정의 변환 시퀀스이다.
9 그렇지 않으면 매개 변수 유형이 클래스가 아닌 경우 :
[…]
이니셜 라이저 목록에 요소가없는 경우 암시 적 변환 순서는 ID 변환입니다. [ 예:
void f(int); f( { } ); // OK: identity conversion
최종 예]
은 std::vector
생성자와 굵은하다고 그것을 사용자 정의 converison 탄환에 의해 초기화된다. 한편,의 int
경우 이는 신원 전환이므로 첫 번째 c’tor의 순위보다 우선합니다.