verherethert. Im folgenden Code wird der Move-Konstruktor der abgeleiteten Klasse offensichtlich nicht generiert, obwohl die Basisklasse move constructible ist.Warum wird der Verschiebungskonstruktor nicht durch die Verwendung der Deklaration
#include <cstddef>
#include <memory>
#include <cstring>
#include <cassert>
template <typename T>
class unique_array : public std::unique_ptr<T[],void (*)(void*)>
{ size_t Size;
protected:
typedef std::unique_ptr<T[],void (*)(void*)> base;
unique_array(T* ptr, size_t size, void (*deleter)(void*)) noexcept : base(ptr, deleter), Size(size) {}
public:
constexpr unique_array() noexcept : base(NULL, operator delete[]), Size(0) {}
explicit unique_array(size_t size) : base(new T[size], operator delete[]), Size(size) {}
unique_array(unique_array<T>&& r) : base(move(r)), Size(r.Size) { r.Size = 0; }
void reset(size_t size = 0) { base::reset(size ? new T[size] : NULL); Size = size; }
void swap(unique_array<T>&& other) noexcept { base::swap(other); std::swap(Size, other.Size); }
size_t size() const noexcept { return Size; }
T* begin() const noexcept { return base::get(); }
T* end() const noexcept { return begin() + Size; }
T& operator[](size_t i) const { assert(i < Size); return base::operator[](i); }
unique_array<T> slice(size_t start, size_t count) const noexcept
{ assert(start + count <= Size); return unique_array<T>(begin() + start, count, [](void*){}); }
};
template <typename T>
class unique_num_array : public unique_array<T>
{ static_assert(std::is_arithmetic<T>::value, "T must be arithmetic");
public:
using unique_array<T>::unique_array;
unique_num_array(unique_num_array<T>&& r) : unique_array<T>(move(r)) {}
unique_num_array<T> slice(size_t start, size_t count) const noexcept
{ assert(start + count <= this->size()); return unique_num_array<T>(this->begin() + start, count, [](void*){}); }
public: // math operations
void clear() const { std::memset(this->begin(), 0, this->size() * sizeof(T)); }
const unique_num_array<T>& operator =(const unique_num_array<T>& r) const { assert(this->size() == r.size()); memcpy(this->begin(), r.begin(), this->size() * sizeof(T)); return *this; }
const unique_num_array<T>& operator +=(const unique_num_array<T>& r) const;
// ...
};
int main()
{ // works
unique_array<int> array1(7);
unique_array<int> part1 = array1.slice(1,3);
// does not work
unique_num_array<int> array2(7);
unique_num_array<int> part2 = array2.slice(1,3);
// test for default constructor
unique_num_array<int> array3;
return 0;
}
Mit dem obigen Code, den ich einen Fehler (gcc 4.8.4):
test6.cpp: In function ‘int main()’: test6.cpp:47:48: error: use of deleted function ‘unique_num_array::unique_num_array(const unique_num_array&)’ unique_num_array part2 = array2.slice(1,3);
Die Scheibe Funktion in der abgeleiteten Klasse kann nicht als Wert zurückgeben, weil der bewegt Konstruktor fehlt. Alle anderen Konstruktoren scheinen zu funktionieren (nicht in diesem Beispiel).
Wenn ich den Move Constructor explizit (Kommentarzeile) definiere, kompiliert das Beispiel. Aber in diesem Fall verschwindet der Standardkonstruktor, der natürlich nicht beabsichtigt ist.
Was geht hier vor? Ich verstehe keinen der Fälle.
Warum wird der Verschiebungskonstruktor im ersten Fall gelöscht?
Warum wird der Standardkonstruktor im zweiten Fall gelöscht? Andere scheinen zu überleben.
[Kompiliert mit g ++ 5.4.0] (http://rextester.com/MXN10456), für das, was es wert ist. –
Sie sollten Zusammensetzung über Vererbung bevorzugen. – Jarod42
Sie könnten 'std :: vector' verwenden. – Jarod42