尝试从 Derived* 的向量分配 Base* 的向量
Trying to assign vector of Base* from vector of Derived*
这似乎是一个非常基本的问题,但我想不通。我有一个指向 Derived 对象的 std::vector
原始指针,我只想使用赋值运算符将它复制到另一个 Base 指针向量。使用 VC++ 我得到错误 C2679 "binary '=': no operator found..." 顺便说一句,我不需要对象的深拷贝,我只想复制指针。示例代码:
#include <vector>
using namespace std;
struct Base{};
struct Derived: public Base {};
int main (int argc, char* argv[])
{
vector<Derived*> V1;
vector<Base*> V2;
V2 = V1; //Compiler error here
return 0;
}
让我感到困惑的是,我可以通过循环并使用 push_back
来复制向量,如下所示:
for (Derived* p_derived : V1)
V2.push_back(p_derived);
所以我的问题是为什么分配失败,而 push_back
有效?对我来说似乎是同样的事情。
push_back
执行逐元素转换。赋值运算符只存在于相同类型的向量之间。
一个简单的解决方案是使用 assign
:
v2.assign(v1.begin(), v1.end());
那是因为Base
和Derived
有关系,而vector<Base*>
和vector<Derived*>
没有关系。就 class 层次结构而言,它们完全无关,因此您不能将一个分配给另一个。
您要查找的概念称为 covariance。例如,在 Java 中,String[]
是 Object[]
的子类型。但是在C++中,这两个类型只是不同的类型,没有比String[]
和Bar
更多的关联。
push_back
之所以有效,是因为该方法仅采用 T const&
(或 T&&
),因此任何可转换为 Base*
的内容都是可以接受的 - [=24] =]是。
就是说,vector
有一个构造函数,它接受一对迭代器,在这里应该更容易使用:
vector<Base*> v2(v1.begin(), v1.end());
或者,因为它已经构建:
v2.assign(v1.begin(), v1.end());
在模板的一般情况下,如果您有 class 个模板
template <typename T> struct Foo {};
Foo<Base>
不是 Foo<Derived>
的基础 class。
因此,你不能这样做:
Foo<Derived> f1;
Foo<Base> f2 = f1;
这似乎是一个非常基本的问题,但我想不通。我有一个指向 Derived 对象的 std::vector
原始指针,我只想使用赋值运算符将它复制到另一个 Base 指针向量。使用 VC++ 我得到错误 C2679 "binary '=': no operator found..." 顺便说一句,我不需要对象的深拷贝,我只想复制指针。示例代码:
#include <vector>
using namespace std;
struct Base{};
struct Derived: public Base {};
int main (int argc, char* argv[])
{
vector<Derived*> V1;
vector<Base*> V2;
V2 = V1; //Compiler error here
return 0;
}
让我感到困惑的是,我可以通过循环并使用 push_back
来复制向量,如下所示:
for (Derived* p_derived : V1)
V2.push_back(p_derived);
所以我的问题是为什么分配失败,而 push_back
有效?对我来说似乎是同样的事情。
push_back
执行逐元素转换。赋值运算符只存在于相同类型的向量之间。
一个简单的解决方案是使用 assign
:
v2.assign(v1.begin(), v1.end());
那是因为Base
和Derived
有关系,而vector<Base*>
和vector<Derived*>
没有关系。就 class 层次结构而言,它们完全无关,因此您不能将一个分配给另一个。
您要查找的概念称为 covariance。例如,在 Java 中,String[]
是 Object[]
的子类型。但是在C++中,这两个类型只是不同的类型,没有比String[]
和Bar
更多的关联。
push_back
之所以有效,是因为该方法仅采用 T const&
(或 T&&
),因此任何可转换为 Base*
的内容都是可以接受的 - [=24] =]是。
就是说,vector
有一个构造函数,它接受一对迭代器,在这里应该更容易使用:
vector<Base*> v2(v1.begin(), v1.end());
或者,因为它已经构建:
v2.assign(v1.begin(), v1.end());
在模板的一般情况下,如果您有 class 个模板
template <typename T> struct Foo {};
Foo<Base>
不是 Foo<Derived>
的基础 class。
因此,你不能这样做:
Foo<Derived> f1;
Foo<Base> f2 = f1;