我想知道是否可以将派生类值的向量转换为基类值的向量。具体来说,我希望能够将基类对象的向量传递给其形式参数采用基类向量的函数。它似乎不可能直接,因为下面的代码示例产生错误(使用g ++):
#include <vector>
class A {
};
class B : public A {
};
void function(std::vector<A> objs) {
}
int main(int argc, char **argv) {
std::vector<B> objs_b;
objs_b.push_back(B());
function(objs_b);
}
test.cc:16:错误:从'std :: vector&lt; B,std :: allocator&lt; B&gt;转换&gt;'到非标量类型'std :: vector&lt; A,std :: allocator&lt; A&gt; &gt;'要求
我希望能够调用函数,而无需使用类型A的元素定义新向量,插入类型为B的元素或更改为指针向量。
答案 0 :(得分:11)
不,不是。 vector<B>
不是vector<A>
的{{1}},而是B
来自A
。你必须以某种方式改变你的功能。
更具惯用性的C ++方法可能是对它进行模板化并让它采用一对迭代器 - 这就是各种标准库函数(<algorithm>
等)以这种方式工作的原因,因为它分离了算法的实现从它正在运作的东西。
答案 1 :(得分:3)
有时可以解决这个问题。在Boost上获取一些战利品以及他们拥有或使用的一些模板元编程包。具体来说,我会考虑is_base_of这些目的与部分模板专业化相结合。
例如,如果你想做一些模板魔术:
template<typename T, bool Allowed>
struct TemplateVectorCode;
您进行模板化类的前向声明。然后使用“true”布尔值进行专门化:
template<typename T> struct TemplateVectorCode<T, true>{
void operator(const std::vector<T>& myVector) const{ //definition in here }
};
最后,您使用is_base_of
将其用于仅以下列方式实例化模板仿函数的实例:
template<typename T, typename Base>
struct MyFunction : TemplateVectorCode<T, boost::is_base_of<Base,T>::value>{
};
需要注意的重点是,由于我们还没有定义TemplateVectorCode<T, false>
,如果您尝试使用类型T
的函数,而编译器不会派生出来,那么编译器将抛出编译错误输入V
。这意味着您可以在一个地方使用相同的代码,而无需编写多个版本的代码。
(如果我搞砸了部分模板专业化,有人请编辑它。我需要去睡觉。)