4
파생 클래스에 소멸자를 추가하면 정의 된 이동 도구 대신 복사 ctor를 사용할 때 컴파일러 오류가 발생합니다 (gcc 4.7 사용).파생 된 경우 소멸자가 정의 된 경우 move ctor 대신 copy ctor 사용
#include <utility>
#include <iostream>
template <typename T>
struct Base
{
T value;
Base(T&& value) :
value(value)
{
std::cout << "base ctor" << std::endl;
}
Base& operator=(const Base&) = delete;
Base(const Base&) = delete;
Base& operator=(Base&& rhs)
{
value = rhs.value;
std::cout << "move assignment" << std::endl;
}
Base(Base&& other) :
value(other.value)
{
std::cout << "move ctor" << std::endl;
}
virtual ~Base()
{
std::cout << "base dtor" << std::endl;
}
};
template <typename T>
struct Derived : public Base<T>
{
Derived(T&& value) :
Base<T>(std::forward<T>(value))
{
std::cout << "derived ctor" << std::endl;
}
~Derived()
{
std::cout << "derived dtor" << std::endl;
}
};
template <typename T>
Derived<T> MakeDerived(T&& value)
{
return Derived<T>(std::forward<T>(value));
}
struct Dummy {};
int main()
{
auto test = MakeDerived(Dummy());
}
이 코드는 gcc-4.5 및 gcc-4.6에서 정상적으로 컴파일됩니다. GCC-4.7에서 오류는 다음과 같습니다
test.cpp: In function ‘int main()’:
test.cpp:61:34: error: use of deleted function ‘Derived<Dummy>::Derived(const Derived<Dummy>&)’
test.cpp:37:8: note: ‘Derived<Dummy>::Derived(const Derived<Dummy>&)’ is implicitly deleted because the default definition would be ill-formed:
test.cpp:37:8: error: use of deleted function ‘Base<T>::Base(const Base<T>&) [with T = Dummy; Base<T> = Base<Dummy>]’
test.cpp:16:3: error: declared here
test.cpp: In instantiation of ‘Derived<T> MakeDerived(T&&) [with T = Dummy]’:
test.cpp:61:34: required from here
test.cpp:54:43: error: use of deleted function ‘Derived<Dummy>::Derived(const Derived<Dummy>&)’
오전 내가 여기서 뭔가를 누락되거나이 또한 GCC 4.7에서 잘 컴파일해야합니까? Derived 클래스에서 소멸자를 주석 처리하면 모두 잘됩니다.
gcc version 4.5.3 (Ubuntu/Linaro 4.5.3-12ubuntu2)
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-11precise2)
기본 멤버가 아닌 파생 클래스의 이동 생성자를 선언 할 필요가 없습니다. 'Derived (Derived && other) : Base (other) {}'은 기본 클래스 복사 생성자를 호출하므로 명시 적으로 std :: move 대신 작동하도록 시도했습니다. 그 맞습니까? –
goji
@ 트로이 예, 맞습니다. '이동'이 필요합니다. 지금까지 이동 생성자를 가질 필요가 없었던 이유는 컴파일러가 표준에 대한보다 엄격한 준수를 시작하기 때문입니다. –
'= default'라고해도 좋을 것 같습니다. :) – goji