Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move a vector<T*> to vector<const T*>

Is it possible to move a vector<T*> to a vector<const T*> without copying it and without relying on reinterpret_cast<>? I.e.

vector<int*> get() {
   return ...;
}

vector<const int*> getConst() {
   return whatgoeshere(get());
}
like image 685
Timmmm Avatar asked Mar 05 '18 11:03

Timmmm


People also ask

Can we change a const vector C++?

Yes, because std::vector is a value-type rather than a reference type. To simplify things: An std::vector considers the values in its buffer as part of itself, so that changing them means changing the vector.

Can you add to a const vector?

You can't put items into a const vector, the vectors state is the items it holds, and adding items to the vector modifies that state. If you want to append to a vector you must take in a non const ref. Show activity on this post. If you have a const vector it means you can only read the elements from that vector.

Can you modify a const vector?

If the vector itself is declared const (as in const std::vector<T*>), then you can't modify the vector, but you can modify the objects. If the pointers are declared const (as in std::vector<const T*>), then you can modify the vector, but not the objects.

Can you use a vector as a queue?

You "can" use a vector over a queue, if the queue lifetime is short or if you know the maximum size of your queue.


2 Answers

I'm going to attack this from another angle. And address a possible design issue. You didn't specify what comes in the ..., but assuming get populates a vector and then returns it, the solution in my view is to lift the code that does the populating outside of both functions.

template<typename Int>
void do_get(std::vector<Int*>& v) {
  // Populate v
}

auto get() {
   std::vector<int*> ret;
   do_get(ret);
   return ret;
}

auto getConst() {
   std::vector<const int*> ret;
   do_get(ret);
   return ret;
}

One source of truth for the populating logic. And while the two original functions are identical, it's negligible. Furthermore on a sane implementation it won't do any superfluous copies, because RVO is amazing.

like image 75
StoryTeller - Unslander Monica Avatar answered Oct 04 '22 19:10

StoryTeller - Unslander Monica


No.

Although a T* may be trivially converted to a const T*, a container of T* is not "related" to a container of const T*, so there is simply no functionality to do what you ask.

Consider also that such functionality might hypothetically assign a int** to a const int**, which is not permitted (there is no special case provided for when the programmer intended this assignment to take place as part of a swap operation, as far as I know).

Furthermore, a reinterpret_cast would merely be hacking over these facts, giving your program undefined behaviour.

You are stuck with three options:

  • Copy the vector (O(n))
  • Make it so that you have the container you wanted in the first place (O(∞))
  • Make it so that you don't need the new container type at all (O(?))
like image 24
Lightness Races in Orbit Avatar answered Oct 04 '22 18:10

Lightness Races in Orbit