user1316642
user1316642

Reputation: 71

Recasting const function

I'm using a library (libtcod) that has an A* pathfinding algorithm. My class inherits the callback base class, and I implement the required callback function. Here is my generic example:

class MyClass : public ITCODPathCallback
{
...
public: // The callback function
   float getWalkCost(int xFrom, int yFrom, int xTo, int yTo, void *userData ) const 
   {
      return this->doSomeMath();
   };
   float doSomeMath() { // non-const stuff }
};

I found a number of examples using const_cast and static_cast, but they seemed to be going the other way, making a non-const function be able to return a const function result. How can I do it in this example?

getWalkCost() is defined by my library that I cannot change, but I want to be able to do non-const things in it.

Upvotes: 0

Views: 269

Answers (2)

Vaughn Cato
Vaughn Cato

Reputation: 64308

The best solution depends on why you want to do non-const stuff. For example, if you have a cache of results that you want to use to improve performance, then you can make the cache be mutable, since that preserves the logical constness:

class MyClass : public ITCODPathCallback
{
...
public: // The callback function
   float getWalkCost(int xFrom, int yFrom, int xTo, int yTo, void *userData ) const 
   {
      return this->doSomeMath();
   };
   float doSomeMath() const { // ok to modify cache here }
   mutable std::map<int,int> cache;
};

Or perhaps you want to record some statistics about how many times the getWalkCost was called and what the maximum x value was, then passing a reference to the statistics may be best:

class MyClass : public ITCODPathCallback
{
...
public: 
   struct WalkStatistics {
     int number_of_calls;
     int max_x_value;

     WalkStatistics() : number_of_calls(0), max_x_value(0) { }
   };

   MyClass(WalkStatistics &walk_statistics)
     : walk_statistics(walk_statistics)
   {
   }

   // The callback function
   float getWalkCost(int xFrom, int yFrom, int xTo, int yTo, void *userData ) const 
   {
      return this->doSomeMath();
   };
   float doSomeMath() const { // ok to modify walk_statistics members here }
   WalkStatistics &walk_statistics;
};

Upvotes: 6

John Zwinck
John Zwinck

Reputation: 249394

You can hack it this way:

  return const_cast<MyClass*>(this)->doSomeMath();

Of course this won't be considered good design by most people, but hey. If you prefer you can instead make doSomeMath() const, and mark the data members it modifies as mutable.

Upvotes: 1

Related Questions