I am doing some refactoring on some older/messy code. I am trying to improve things little by little. Because it fit the project, I started implementing CRTP (for static polymorphism) on some class, let's call it sensor. Through CRTP, there is now a real and a fake implementation.
Now, I am trying to put templates in a class (interface_actions) that uses sensor. I arrived at something like that:
class interface_actions
{
public:
template <class implementation>
interface_actions(sensor<implementation> detector)
: _detector(detector)
{}
// Lots of stuff that I don't want to touch
private:
#if (SOMETHING)
sensor<real> _detector;
#else
sensor<fake> _detector;
#endif
};
As you can see, I did not know what to do with _detector without having to make the entire class a template, so I used the preprocessor ...
This is more of an architectural question I guess, but how would you go about making _detector take sensor without making the entire class a template?
It seems to me that I would have to fundamentally rewrite this part of the code, but maybe there is a simpler way?
CodePudding user response:
you can use std::conditional_t:
class interface_actions
{
std::conditional_t<SOMETHING, sensor<real>, sensor<fake>> _detector;
};
if SOMETHING yields true, _detector will be of type sensor<real>, sensor<fake> otherwise.
but this only works if SOMETHING is outside of the scope of class interface_actions, otherwise you have to make the class take a template. As pptaszni suggested you could make a default template parameter to "hide" the template argument, so your old code that says interface_actions object; won't be affected:
template<bool is_real = true>
class interface_actions
{
std::conditional_t<is_real, sensor<real>, sensor<fake>> _detector;
};
int main() {
interface_actions foo;
static_assert(std::is_same_v<decltype(foo._detector), sensor<real>>);
}
