想象一下下面的例子:模板化拷貝構造
#include <iostream>
#include <vector>
struct Base
{
virtual void foo() = 0;
};
struct A : public Base
{
void foo() override {};
};
struct B : public Base
{
void foo() override {};
};
template <typename T>
struct C
{
struct Element
{
int x, y, z;
bool operator==(const Element& e)
{
if (x != e.x) return false;
if (y != e.y) return false;
if (z != e.z) return false;
return true;
}
};
Base* p;
std::vector<Element> v;
C()
{
p = new T();
}
void add(int x, int y, int z)
{
Element e;
e.x = x;
e.y = y;
e.z = z;
v.push_back(e);
}
void remove(int x, int y, int z)
{
Element e;
e.x = x;
e.y = y;
e.z = z;
std::vector<Element>::iterator it = std::find(v.begin(), v.end(), e);
if (p != v.end()) v.erase(p);
}
void print()
{
for (Element e : v) std::cout << e.x << " " << e.y << " " << e.z << std::endl;
}
};
int main()
{
C<A> a;
a.add(1, 2, 3);
a.add(4, 5, 6);
a.add(7, 8, 9);
a.remove(4, 5, 6);
a.print();
return 0;
}
現在讓我們添加一個拷貝構造函數用C,使我們可以與持有另一種數據類型(只要數據 - 另一種C初始化Ç類型來自Base)。我們的目標是使這成爲可能:
int main()
{
C<A> a;
a.add(1, 2, 3);
a.add(4, 5, 6);
a.add(7, 8, 9);
a.remove(4, 5, 6);
a.print();
C<B> b(a); // <----- This should be possible.
return 0;
}
我試圖解決這個問題是這樣的:
template <typename U>
C(const C<U>& c)
{
p = new U(*c.p);
v = c.v;
}
,但我得到從Visual Studio這些2個錯誤:
錯誤C2679二進制'=':找不到操作符,它需要一個類型爲'const std :: vector :: Element,std :: allocator < _Ty >>'的右側操作數'(或者沒有可接受的轉換)
錯誤C2664 'A :: A(A & &)':無法從 '基地' 轉換參數1 'const的一個&'
據我瞭解,性病::向量已經有一個賦值運算符實現,該賦值運算符應該在運算符的右側創建向量的深層副本。
那麼我做錯了什麼,我需要做些什麼才能使它工作?
您可能需要爲您的Base類添加一個'virtual Base * clone()const = 0;'並在派生類中重寫它以執行實際的克隆,然後調用它來複制'p'。 – evan