I often have a problem with const correctness when wrapping algorithms in classes in c++. I feel that I want a mutable function, although this is not allowed. Can anyone advise me how to implement classes such as the one that follows?
The following is the code that I want to write.
- The function run() should not be a const function because it changes the data.
- The function get_result() should be a constant function (as far as the user is concerned) because it returns the data.
However, if the user requests the result without calling run(), I want the get_result() function to run the algorithm. This breaks the const correctness because I have a const function calling a non-const function.
class operate_on_data
{
std::vector<double> m_data; // the data to modify
bool m_completed; // check to see if the function run() has been called
public:
operate_on_data(std::vector<double> data)
: m_data(data), m_completed(false) {} //initialise
void run() //I don't want this function to be const
{
//The algorithm goes here - it alters m_data.
m_completed = true; //the algorithm has been run
}
std::vector<double> get_result() const //I want this function to be const
{
/*The following breaks const correctness because
I am calling a non-const function from a const function
- but this feels like the right thing to do ... */
if (!m_completed) run(); //run the algorithm if it has not run already
return m_data; //return
}
};
The only way I have been I have managed to compile the above class is to either
- make run() const, and make m_data and m_completed mutable. This works but is conceptually wrong because run() demonstrably changes data.
- make get_result() not a constant function. This seems wrong too, for the user would expect this function to be a simple return, and therefore constant.
- Put the run() function into the get_result() const function and make the data variables mutable.
My understanding was that the mutable keyword was designed for the third of these options, where the implementation requires data to be changed but the user reasonably expects a simple return and therefore const function.
However, I don't want to do this final option because I want the user to be able to choose exactly when they change the data. There is a chance that they will forget to call run(), however, and so I want to force the algorithm if they request the result without calling run(). I feel like a want to make run() mutable - but I'm not allowed to.
What is the correct way to write such a class?