I have a class like this one:
struct Base
{
void aa(int n) const {
std::cout << "aa() " << field*n << std::endl;
}
void bb(int n) const {
std::cout << "bb() " << field*n*2 << std::endl;
}
int field = 2;
};
I want to be able to select, at compile time, one of the two implementations, aa()
or bb()
, via a call to an operator method. Something like:
Base data;
Magic obj(data);
obj.as_AA() * 33; // should call data.aa(33)
obj.as_BB() * 44; // should call data.bb(44)
data
must not be duplicated. And the choice of aa()
vs bb()
must be resolved at compile time.
I have a solution which uses a downcasting whose behavior is in theory undefined (I think). It builds (with g++ and clang++) and runs perfectly, but still ...
struct AA : public Base
{
void operator*(int n) const {
return Base::aa(n);
}
};
struct BB : public Base
{
void operator*(int n) const {
return Base::bb(n);
}
};
struct Chooser
{
Base obj;
template<typename WHICH> // will be either AA or BB
const WHICH& as() const {
return static_cast<const WHICH&>( obj ); // downcasting
}
};
In main.cpp
:
Chooser ch;
ch.as<AA>() * 5; // prints "aa() 10"
ch.as<BB>() * 7; // prints "bb() 28"
How unreliable is my solution? (because of the downcasting which is technically undefined)
Do you see alternatives?
Thanks
ps: of course I could trivially use
Base data;
data.aa(33);
data.bb(44);
but I really want to access the different implementations via the same name, ie., the operator*
I could also use a templated operator* in Base
and have explicit template specializations, however that would force me to use an ugly syntax, which kind of voids the purpose of the operator:
struct Base {
\\...
template<int N> void operator*(int n) const;
};
template<> void Base::operator*<1>(int n) const {
aa(n);
}
Which requires:
Base data;
data.operator*<1>(44); // ugly