如何在转换向量时避免复制到向量
当函数需要一个带有(指向)基类对象的向量作为输入但我只有一个(指向)派生对象的向量时,有没有办法避免复制大向量?
class Base {};
class Derived : public Base {};
void doStuff(vector<Base*> &vec)
{
//do stuff with vec objects
}
int main()
{
vector<Derived*> fooDerived(1000000);
vector<Base*> fooBase(fooDerived.begin(), fooDerived.end()); // how to avoid copying here?
doStuff(fooBase);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您可以像使用
vector
一样使用vector
,则可以添加一个指向OtherDerived 类的指针: public Base
到该向量。这会很危险。If you could use a
vector<Derived*>
as if it where avector<Base*>
, you could add a pointer to aclass OtherDerived : public Base
to that vector. This would be dangerous.您无法投射向量。但是,您实际上也不需要这样做。
如果你真的想要,你可以使用Boost Iterator (文档)
注意:使用
dynamic_cast
是如果对象的运行时类型无法转换为Derived*
(例如,因为它实际上是一个OtherDerived*
,所以它只会返回一个null
指针。You can't cast the vectors. However, you shouldn't really need to either.
If you really want, you could use Boost Iterator (documentation)
Note: a particularly handy effect of using
dynamic_cast<Derived*>
is that if the runtime type of the object cannot be casted toDerived*
(e.g. because it is actually anOtherDerived*
, it will simply return anull
pointer.如果您对
doStuff()
的定义是绝对强制的,那么您将无法绕过副本。由于多种原因,指针的容器相对于被指向者的类层次结构不是“协变”的。 (例如,如果您可以将vector
视为vector
,则可以插入Base
指针无论如何,容器的参数类型是固定的,并且是容器类型的一部分。)如果您对该函数确实有一些余地,那么您 可以使用派生指针。可以重构代码一点:您可以将其设置为容器上参数化的模板,或者迭代器范围上的模板,和/或者您可以将实际工作负载拆分为单独的函数。例如:
If your definition of
doStuff()
is absolutely mandatory, then you won't get around the copy. Containers of pointers aren't "covariant" with respect to the pointee's class hierarchy, for a whole host of reasons. (For example, if you could treatvector<Derived*>
like avector<Base*>
, you could insertBase
-pointers into it which wouldn't behave likeDerived
-pointers. In any event, the parameter type of a container is fixed and part of the container's type.)If you do have some leeway with the function, you could restructure the code a bit: You could make it a template parametrized on the container, or a template on an iterator range, and/or you could split the actual workload into a separate function. For example:
由于向量的模板是一个指针,因此您的 fooBase 局部变量将使用引用。可能问题不是很清楚,如果您能说清楚的话我们可能会尽力解决问题!
Since your template for the vector is a pointer, your fooBase local variable is going to be using reference. Maybe the question is not very clear, if you could specify clearly we may try to address the problem!
一种方法是仅存储指向基类的指针,如下所示:
One way is to store only pointers to the base class like this:
我发现这个主题很有趣,他们提到你可以安全地转换
Derived*< /code> 到
Base*
(但不是另一侧),而从vector
到vector < 是不可能的/code> 但你好心of 应该能够...(好吧,向量的地址发生变化,因此需要一个副本) >(vector)
但不确定它是否比使用复制构造函数更好......可能会发生同样的事情。他们提到的一个肮脏的解决方案是使用reinterpret_cast
I found this topic interesting where they mention you can safely cast
Derived*
toBase*
(but not the other side) while this is not possible fromvector<Derived*>
tovector<Base*>
but you kind of should be able to... (Ok, the address of the vector changes, thus needing a copy)One dirty solution they mention is using
reinterpret_cast<vector<Base*> >(vector<Derived*>)
but not sure if it's better then using the copy constructor... probably the same thing happens.