比方说,我有一个Storage
的某些Object
s,它有一个方法可以汇总指向某个向量中某些Objects
的指针。就像这样:有没有办法将std :: vector <const T*>转换为std :: vector <T*>而无需额外分配?
class Storage
{
public:
std::vector<Object*> aggregate_some_objects(); // non-const version
std::vector<const Object*> aggregate_some_objects() const; // const version
private:
std::unordered_map<size_t, Object> m_objects; // data is stored
// by-value in a non-vector container
}
通常,没有办法避免在执行常量+非const方法对复制粘贴通过调用其他内其中一人的const_cast
帮助。然而,这是不可能的,因为这些方法的返回类型是不同的。
最直接的方式,以避免在这里复制粘贴将来自非const
版本叫const
版本,并使用返回std::vector<const T*>
来填充一个单独的std::vector<T*>
。但是,这将导致至少2堆分配(每个向量一个)。我想避免与第二个向量相关联的分配。
我不知道是否有办法写类似
template <typename T>
std::vector<T*> remove_const_from_vector_of_ptrs(std::vector<const T*>&& input)
{
std::vector<T*> ret;
// do some magic stuff here that does not involve
// more memory allocations
return ret;
}
因此,允许写
std::vector<const Object*> Storage::aggregate_some_objects() const
{
// non-trivial implementation
}
std::vector<Object*> Storage::aggregate_some_objects()
{
auto objects = const_cast<const Storage*>(this)->aggregate_some_objects();
return remove_const_from_vector_of_ptrs(std::move(objects));
}
有一个在std::vector
(如std::unique_ptr
例如)没有“释放”的方法,使转移内存所有权 - 出于一个很好的理由,所以我认为这是不可能的。
我也明白,如果可能的话,这应该是一个危险的操作,应该被普遍避免,就像const_cast
一样。但是,像这样的情况下的谨慎使用似乎比复制粘贴更有用。
编辑:添加澄清说明,对我是什么“额外”的分配意味着,改变Storage::aggregate_objects()
到Storage::aggregate_some_objects()
更好地表明,这些方法的实现是比较复杂的,然后基于范围的循环 - 因此避免复制的愿望 - 实施。
你的函数按值返回,所以每次都要分配一个新的向量。你想避免什么“额外分配”? –
是的,函数返回的值,这意味着至少有一个堆分配必须发生(最好的情况下 - 我知道返回的矢量的大小,并可以调用'vector :: reserve')。我正在谈论的分配将发生在最简单的有关方法的实现中,不涉及拷贝粘贴:非''constst'版本调用'const'版本(它返回'std :: vector')和填充单独的'std :: vector '。创建一个单独的向量将导致至少一个('额外')分配,我想避免。在问题中澄清了这一点。 –
如果你的目标只是为了避免重复函数体,那么不要试图对任何模糊和未定义的行为做任何愚蠢的事情,只需编写一个返回'std :: vector'的函数模板,然后用'T' = ='Object'或者'T' =='const Object'。 –