My program has a Car and CarManager class that looks similar to the following:
#include <list>
class Car
{
public:
void Draw() { Draw(m_opacity); }
void Draw(float opacity)
{
}
private:
float m_opacity;
};
class CarManager
{
public:
//Draw cars using their m_opacity member
void DrawCars()
{
for(auto i = m_cars.begin(); i != m_cars.end(); i++)
i->Draw();
}
//Draw cars using opacity argument
void DrawCars(float opacity)
{
for(auto i = m_cars.begin(); i != m_cars.end(); i++)
i->Draw(opacity);
}
private:
std::list<Car> m_cars;
}
MyApplication::OnRender()
{
CarManager* pCarManager = GetCarManager();
//If this condition is met, I want all cars to be drawn with 0.5 opacity.
if(condition)
pCarManager->DrawCars(0.5f);
//Otherwise, draw cars using their m_opacity value.
else
pCarManager->DrawCars();
}
C++ doesn’t allow a non-static member to be used as a default argument, so I have overloaded the Drawing functions. If no argument is supplied, an overloaded version of the function will be called using the class member.
Each car has an m_opacity member which is used for rendering. However, there are certain situations where I would like to specify a value for the opacity that I would like all cars to use. In these cases, I would like m_opacity to be ignored in favor of the value that I provide.
In this example, the rendering code in CarManager::DrawCars() is rather small so repeating the same code with a different call to Car::Draw() isn’t a big deal. But in my actual program, repeating all of the same code is not practical.
This is starting to get messy. Is there a better way to go about this?
There are several ways to deal with the problem:
optional<T>which basically bundles aTwith an indication on whether the object is actually present deals with one special value. If the choice is, indeed, binary (use the passed opacity or the object’s one), this can work: the default would use anoptional<T>indicating that the optional argument is absent and otherwise its value would be use.Carobject:std::function<double(Car const&)>. The default would be a function which obtains theCar‘s opacity but it could be some other function, including always return a constant.Since the third option is a bit more obscure I’ll provide an example below (which assumes that the
Carhas a member functionopacity()returning theCar‘s opacity):It is now easy to pass in other function objects somehow copying the opacity: