2

If I have a class, say,

class Car {
  public:
    void Drive();
    void DisplayMileage() const;
};

And I create a shared pointer based on this class,

typedef boost::shared_ptr<Car> CarPtr;

And I then go on to populate a vector of CarPtrs,

std::vector<CarPtrs> cars...;

I now want to iterate over the vector and do some stuff:

for(auto const &car : cars) {
   car->DisplayMileage(); // I want this to be okay
   car->Drive(); // I want the compilation to fail here because Drive isn't const.
}

Is this possible without casting the shared pointer to a car to a shared pointer to a const car?

Escualo
  • 40,844
  • 23
  • 87
  • 135
freddy.smith
  • 451
  • 4
  • 9

2 Answers2

8

Sounds like a good use case for the Boost.Range "indirected" adaptor:

for(auto const& car : cars | boost::adaptors::indirected) {
  car.DisplayMileage();
  car.Drive(); // error: passing 'const Car' as 'this' argument of 'void Car::Drive()' discards qualifiers [-fpermissive]
}

Working demo code here.

Casey
  • 41,449
  • 7
  • 95
  • 125
  • Brilliant, thank you! This is exactly what I wanted to do without changing the original definition, it was an academic exercise, but great answer. Thanks again. – freddy.smith Apr 26 '13 at 19:43
2

Is this possible without casting the shared pointer to a car to a shared pointer to a const car?

No, it is not possible. The const applies to the shared pointer, not to the thing it refers to.

This is a basic fact of indirection, and it is the same with pointers:

int main()
{
   int x = 0;
   int* p1 = &x;
   auto const p2 = p1;

   // p2 is `int* const`, not `int const*`
   *p1 = 1;
}

It's arguably unfortunate that there's simply no way to inherently gain immutability in your iteration, but that's because you're employing indirection: you're not iterating over Cars.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 3
    Sometimes, my favorite part of SO is "no, it is not possible" answers (which make perfect sense, and are correct!) immediately adjacent to "sure, this is easy with `boost`" answers. – Yakk - Adam Nevraumont Apr 27 '13 at 00:04