기본 클래스가 아닌데 파생 클래스 이동을 구성 할 수있는 이유는 무엇입니까?
다음 예를 고려하십시오.
#include <iostream>
#include <string>
#include <utility>
template <typename Base> struct Foo : public Base {
using Base::Base;
};
struct Bar {
Bar(const Bar&) { }
Bar(Bar&&) = delete;
};
int main() {
std::cout << std::is_move_constructible<Bar>::value << std::endl; // NO
std::cout << std::is_move_constructible<Foo<Bar>>::value << std::endl; // YES. Why?!
}
기본 클래스가 이동 구성이 불가능 함에도 불구하고 컴파일러가 이동 생성자를 생성하는 이유는 무엇입니까?
표준에 있습니까 아니면 컴파일러 버그입니까? 기본에서 파생 클래스로 이동 구성을 "완벽하게 전파"할 수 있습니까?
때문에:
삭제 된 것으로 정의 된 기본 이동 생성자는 오버로드 확인에서 무시됩니다.
([class.copy] / 11)
Bar
의 이동 생성자가 명시 적으로 삭제 되었으므로 Bar
이동할 수 없습니다. 그러나 Foo<Bar>
의 이동 생성자는 멤버를 이동할 수 없기 때문에 기본값으로 암시 적으로 선언 된 후 암시 적으로 삭제됩니다Bar
. 따라서 Foo<Bar>
복사 생성자를 사용하여 이동할 수 있습니다.
편집 : 또한 상속 생성자 선언이 using Base::Base
기본, 복사 또는 이동 생성자를 상속하지 않는다는 중요한 사실을 언급하는 것을 잊었 으므로 Foo<Bar>
명시 적으로 삭제 된 이동 생성자가에서 상속되지 않습니다 Bar
.
1. 행동 std::is_move_constructible
이것은 std :: is_move_constructible 의 예상 동작입니다 .
이동 생성자가 없지만
const T&
인수 를 허용하는 복사 생성자가있는 유형은std::is_move_constructible
.
즉, 복사 생성자를 사용하면 T
rvalue reference에서 생성 할 수 있습니다 T&&
. 그리고 Foo<Bar>
가 암시 적으로 선언 복사 생성자를 .
2. 암시 적으로 선언 된 이동 생성자 Foo<Bar>
기본 클래스가 이동 구성이 불가능 함에도 불구하고 컴파일러가 이동 생성자를 생성하는 이유는 무엇입니까?
실제로의 이동 생성자는 deletedFoo<Bar>
로 정의되지만 삭제 된 암시 적으로 선언 된 이동 생성자는 오버로드 확인에서 무시됩니다.
클래스
T
에 대한 암시 적으로 선언되거나 기본 이동 생성자 는 다음 중 하나가 참인 경우 삭제 된 것으로 정의됩니다.... T has direct or virtual base class that cannot be moved (has deleted, inaccessible, or ambiguous move constructors); ...
삭제 된 암시 적으로 선언 된 이동 생성자는 오버로드 확인에서 무시됩니다 (그렇지 않으면 rvalue에서 복사 초기화가 방지 됨).
3. Bar
와 사이의 다른 행동Foo<Bar>
의 이동 생성자는 명시 적으로 Bar
선언 deleted
되고의 이동 생성자 Foo<Bar>
는 암시 적으로 선언되고로 정의됩니다 deleted
. 요점은 삭제 된 암시 적으로 선언 된 이동 생성자가 오버로드 해결에 의해 무시 되므로 Foo<Bar>
복사 생성자 로 구성을 이동할 수 있다는 것 입니다. 그러나 명시 적으로 삭제 된 이동 생성자는 오버로드 해결에 참여합니다. 즉, 생성자를 이동하려고 할 때 Bar
삭제 된 이동 생성자가 선택되고 프로그램이 잘못 구성됩니다.
그렇기 때문에 Foo<Bar>
이동 시공이 가능하지만 Bar
그렇지 않습니다.
표준에는 이것에 대한 명시적인 진술이 있습니다. $ 12.8 / 11 클래스 개체 복사 및 이동 [class.copy]
삭제됨으로 정의 된 기본 이동 생성자는 오버로드 확인 ([over.match], [over.over])에서 무시됩니다. [참고 : 삭제 된 이동 생성자는 복사 생성자를 대신 사용할 수있는 rvalue의 초기화를 방해합니다. — 끝 참고]
'Programing' 카테고리의 다른 글
doubleclick 이벤트가있는 Jquery .on (0) | 2020.12.27 |
---|---|
& ((struct name *) NULL-> b)는 C11에서 정의되지 않은 동작을 유발합니까? (0) | 2020.12.27 |
블록에`@ ts-ignore`를 사용하는 방법 (0) | 2020.12.27 |
'+'연산자없이 문자열 연결 (0) | 2020.12.27 |
Xcode 오류 :“개발 팀에 앱 ID를 등록 할 수 없습니다.” (0) | 2020.12.27 |