std :: vector 범위 생성자가 명시 적 변환을 호출 할 수 있습니까? explicit A(int)

다음 프로그램이 제대로 구성되어 있습니까?

#include <vector>
struct A {
    explicit A(int) {}
};
int main() {
    std::vector<int> vi = {1, 2, 3, 4, 5};
    std::vector<A> va(vi.begin(), vi.end());
}

C ++ 17 [sequence.reqmts]에 따르면

X u(i, j);

X시퀀스 컨테이너는 어디에 있습니까?

T한다 EmplaceConstructibleX에서 *i.

그러나 이전 단락에서는 다음과 같이 명시되어 있습니다.

ij입력 반복자 요구 사항을 만족하는 반복자 를 표시하고로 암시 적으로 변환 가능한 요소를 참조하십시오 value_type.

따라서이 두 요구 사항이 충족 될 필요가있을 것이다 나에게 보인다 범위의 값 유형이 컨테이너의 값 유형을 암시 적으로 변환 할 수 있어야 하고 EmplaceConstructible (할당자가 필요한 초기화를 수행 할 수 있어야 의미)을 만족해야한다 . 로 int암시 적으로 변환 A할 수 없으므로이 프로그램은 잘못 구성되어야합니다.

그러나 놀랍게도 GCC에서 컴파일되는 것 같습니다 .



답변

암시 적 변환 기준을 만족시키는 반복자로부터의 구성을 지원하기 위해서는 시퀀스 컨테이너가 필요합니다.

이것은 내가 말할 수있는까지로 그 기준을 만족하지 않는 반복자에서 해당 건설 지원에서 자체에 의해 해제하면 시퀀스 컨테이너를하지 않는 1 . 그것에 대한 명백한 규칙이 있습니다.

생성자 …가 입력 반복자 자격 이없는 InputIterator 유형으로 호출 되면 생성자는 과부하 해결에 참여하지 않아야합니다.

문맥에서 “입력 반복자로서의 자격”이 정확히 무엇을 의미하는지는 확실하지 않습니다. Cpp17InputIterator를 표현하는 비공식적 인 방법입니까, 아니면 i와 j의 요구 사항을 참조하려고합니까? 모르겠어요 허용 여부에 관계없이 표준에는이를 감지하기위한 엄격한 요구 사항이 없습니다.

[container.requirements.general]

특정 컨테이너 멤버 기능 및 추론 가이드의 동작은 유형이 입력 반복자인지 할당 자인지에 따라 다릅니다. 구현이 유형을 입력 반복자가 될 수 없다고 결정하는 정도는 최소 정수 유형으로서 입력 반복자로 자격이되지 않는 것을 제외하고는 지정되지 않습니다. …

모든 Cpp17InputIterator가 “입력 반복자로 자격이 있다는”해석으로 예제 프로그램이 잘못 구성 될 필요는 없습니다. 그러나 올바른 형식을 보장하지는 않습니다.

1 그러한 경우, 의존 할 때 경고하는 구현 품질 문제로 간주 될 수 있습니다. 반면에 암시 적 변환에 대한 이러한 제한은 결함 으로 간주 될 수 있습니다 .


추신 이것은 Clang (libc ++)과 Msvc에서도 경고없이 컴파일됩니다.

PPS이 표현은 C ++ 11에 추가 된 것으로 보입니다 (명시적인 생성자가 도입 된 것처럼 자연 스럽습니다).