함수 인수로서 {}가 왜 모호성을 유발하지 않습니까?


20

이 코드를 고려하십시오.

#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>?

생성자 서명은 확실히 더 잘릴 수는 있지만 동등한 코드 조각에 속아서이 질문에 중요한 것이 없어야합니다.


{}코드 블록으로 corretly 를 호출 하면 변수에 0을 할당합니다. 예 : const char x = {}; int 등과 동일하게 0 (null char)으로 설정됩니다.
Seti

2
@Seti {}특정 특수한 경우에 효과적으로 수행되는 것이지만 일반적으로 정확 하지는 않습니다 (초보자, std::vector<int> x = {};작업, std::vector <int> x = 0;그렇지 않음). " {}0을 할당 "하는 것만 큼 간단하지 않습니다 .
Max Langhof

그렇습니다. 그렇게 간단하지는 않지만 여전히 0을 할당합니다.이 행동은 매우 혼란스럽고 실제로 사용해서는 안된다고 생각합니다.
Seti

2
@Seti struct A { int x = 5; }; A a = {};는 어떤 의미로도 0을 할당하지 않으며 Awith를 구성합니다 a.x = 5. 이는 0으로 A a = { 0 };초기화되는 것과 달리 a.x0은 고유하지 않으며 {}각 유형이 기본 구성 또는 값으로 초기화되는 방식에 고유합니다. 여기 , 여기여기를 참조 하십시오 .
Max Langhof

나는 여전히 기본 구성 가치가 혼란 스럽다고 생각한다 (행동을 점검하거나 많은 지식을 항상 유지해야 함)
Seti

답변:


12

이 글은 다음의 [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의 순위보다 우선합니다.


예, 정확 해 보입니다.
콜 럼보

이 상황이 표준에서 명시 적으로 고려된다는 점에 흥미가 있습니다. 나는 그것이 모호하다고 기대했을 것입니다 (그리고 그렇게 쉽게 지정 될 수있는 것처럼 보입니다). 나는 당신의 마지막 문장에서 추론을 따를 수 없습니다- 0유형이 int있지만 유형이 아닙니다 std::vector<int>. 어떻게 "as as"가 "untyped"본성에 {}어떻습니까?
맥스 랭 호프

@MaxLanghof-그것을 보는 다른 방법은 클래스가 아닌 유형의 경우 사용자 정의 변환이 아닙니다. 대신 기본값의 직접 초기화 프로그램입니다. 따라서이 경우 정체성.
StoryTeller-Unslander Monica

그 부분은 분명하다. 에 대한 사용자 정의 변환이 필요하다는 것에 놀랐습니다 std::vector<int>. 당신이 말했듯이, 나는 "매개 변수의 유형이 인수의 유형을 결정하게된다"고 예상했고, {}"유형"(그렇게 말하면) std::vector<int>은 (비 식별) 변환을 필요로하지 않아야합니다 std::vector<int>. 표준은 분명히 그렇게 말합니다. 그렇지만 나에게는 이해가되지 않습니다. (내 생각에, 나는 당신이나 표준이 잘못되었다고 주장하지 않고, 단지 이것을 나의 정신 모델과 조화 시키려고 노력하고있다.)
Max Langhof March

좋아, 그 편집은 내가 원했던 해결책이 아니라 공평했다. : D 시간 내 주셔서 감사합니다!
맥스 랭 호프
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.