想象一下下面的例子:模板化拷贝构造
#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