함수 인수로서 {}가 왜 모호성을 유발하지 않습니까? { std::cout << “int overload” <<

이 코드를 고려하십시오.

#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);
}

https://godbolt.org/z/Gc_w8i

인쇄합니다 :

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의 순위보다 우선합니다.


답변