Suppose I have a struct that has a name and some value associated with it:
struct Season {
std::string name;
// Mean temperature over the season
double meanTemperature;
// Days since the start of year when it's strongest
float strongestAt;
// Fraction of a year it applies to, compared to other seasons
float yearFraction;
}
This class describes a season per year. Suppose I have a collection of them, which fills in the entire year:
// made up method that is supposed to find a season (I don't use it in real code)
int findIndex(const std::vector<Season>& in, std::function<bool(const Season&)>);
class SeasonCollection
{
public:
const Season* GetSeason(const std::string& name) const
{
const int index = findIndex(_seasons, [name](const Season& s) { return s.seasonName == name; });
return index != -1 ? &_seasons[index] : nullptr;
}
Season* GetSeason(const std::string& name)
{
const int index = findIndex(_seasons, [name](const Season& s) { return s.seasonName == name; });
return index != -1 ? &_seasons[index] : nullptr;
}
private:
//! Settings for seasons
std::vector<Season> _seasons;
};
In that collection you can see that I need to get both const Season*
and Season*
. That's because in some contexts, the collection is meant to be read-only and in some others, it is writeable.
There will also be other ways of getting a season, such as day of the year (eg. Christmas day 24.12
). I want to have a const
getter for each method of getting them, but I also do not want to copy-paste each of them and just add const
.
What's the best approach?
I hate to say it, but const_cast
. What you do is make and call the const
getter, and just remove the const
that it returns since you know you are in a non-const object inside the non const getter. That would look like
const Season* GetSeason(const std::string& name) const
{
const int index = findIndex(_seasons, [name](const Season& s) { return s.seasonName == name; });
return index != -1 ? &_seasons[index] : nullptr;
}
Season* GetSeason(const std::string& name)
{
return const_cast<Season*>(const_cast<SeasonCollection const *>(this)->GetSeason(name));
// ^ remove the const^ ^ add const to call the const getter ^^call const getter^
}