Let's say I have a Storage of some Objects which has a method that aggregates pointers to some of the Objects in a vector. Like this:
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
}
Generally, there is way to avoid copy-paste in implementation of const + non-const method pairs by calling one of them inside the other with the help of const_cast. Here however this is not possible because the return types of the methods are different.
The most straightforward way to avoid copy-paste here would be to call const version from a non-const version and use the returned std::vector<const T*> to populate a separate std::vector<T*>. However this would lead to at least 2 heap allocation (one for each vector). I would like to avoid the allocations associated with the second vector.
I wonder if there is way to write something like
template <typename T>
std::vector<T*> remove_const_from_vector_of_ptrs(std::vector<const T*>&& input)
{
std::vector<const T*> ret;
// do some magic stuff here that does not involve
// more memory allocations
return ret;
}
Thus, allowing to write
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));
}
There is no 'release' method in std::vector (like std::unique_ptr for example) that allows transferring of memory ownership - and for a very good reason, so I expect that this is not possible.
I also understand that if it were possible, it would be a dangerous operation that should be generally avoided, just as const_cast. But a careful usage in cases like this seems more beneficial than copy-pasting.
Aucun commentaire:
Enregistrer un commentaire