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


14

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

#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에서 컴파일되는 것 같습니다 .


(기록을 위해 그것은 단지 gcc : godbolt.org/z/ULeRDw가 아닙니다 )
Max Langhof

이 경우 명시 적 생성자가 이미 형식에 맞기 때문에 암시 적 변환이 필요하지 않습니다. 설명이 혼란 스럽지만 명시 적 구성이 항상 암시 적 변환보다 낫습니다.
JHBonarius

답변:


2

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

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

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

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

[container.requirements.general]

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

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

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


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

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


1
"입력 반복자로 자격이 없음"의 의미 에 따라 달라집니다 . 위와 달리 실제로는 말하지 Cpp17InputIterator않기 때문에 "암시 적으로 변환 할 수있는 요소를 참조하는 value_type" 이 "입력 반복자"에 포함되어 있는지 확실하지 않습니다 . 만약 그렇다면, 생성자는 과부하 해결에 참여하지 않아야하고 프로그램은 잘못된 형식이어야합니다.
Max Langhof

1
따라서 모든 표준 라이브러리 클래스에는 추가 생성자가 사용될 때 진단을 발행하지 않고 추가 생성자가있을 수 있습니까? 그것은 직관적으로 나에게 잘못 보인다 ...
Brian

@Brian "추가 생성자"인지 확실하지 않지만 "더 많은 공간을 허용하는 생성자의 특정 구현"일 수도 있습니다. 모든 입력을 확인하면 성능에 상당한 영향을 줄 수 있으므로 이것이 좋은 방법인지 모르겠습니다.
JHBonarius

@Brian 명시 적으로 허용되지 않더라도 확실히 나쁜 생각입니다. 이 경우, 필수 생성자가 지원하지 않아도되는 반복자 유형을 지원할 수 있는지 여부 만 고려하고 있습니다. 이 경우 Max에서 지적한 바와 같이 명시 적으로 "참여해서는 안됩니다"라는 요구 사항이 있으며, 이는 분명히이를 허용하지 않습니다. 그러나 문맥에서 "입력 반복자로서의 자격"이 정확히 무엇을 의미하는지는 확실하지 않습니다. 그것을 표현하는 비공식적 인 방법입니다 Cpp17InputIterator, 또는 그것의 요구 사항을 참조하려고 않습니다 ij? 모르겠어요
eerorika

2
1) C ++에서는 표준을 낮게 설정했습니다. . 2) 생성자는 비가 상 멤버 함수 입니다. 3) LWG 3297 참조 ; 그러나 특히 암시 적 변환 요구 사항을 제거해야한다고 확신하지는 않습니다.
TC
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.