Greetings all.
I am writing some code using the Boost Units library and have run into a problem.
I have managed to abstract the problem from Boost code so you won’t be looking through reams of boost template meta programming. Though I’m sure if you have experience with that it could help. Here is the reproduction:
class Base{};
class Derived : public Base
{
public:
Derived(){}
Derived(const Base &){}
};
class Q {};
class U
{
public:
template< typename Y >
Q operator * (Y)
{
Q r;
return r;
}
};
Base operator * (U, const Base &)
{
Base r;
return r;
}
int main(int argc, char **argv)
{
Base myBase;
U myU;
Base myOtherBase = myU * myBase;
Derived myDerived;
Derived myOtherDerived = myU * myDerived;
return 0;
}
So the problem (specifically) is as follows: myU * myBase uses operator * (U, const Base &) and returns type of Base, all good so far. Whereas myU * myDerived insists on using generalised U::operator * (Y) and hence returns a Q, no good because I wanted a Base again.
Now, all classes other than Base and Derived are boost library classes so I cannot modify the members of U. How do I “beat” U::operator * (Y) for overload/template deduction/instantiation, in this case, in an elegant and “solved once and for ever” manner.
I am using MSVC++ 2008 in case it is relevant to anyone.
Edit: Added a possible (quite likely) solution in answers
Just as I gave up trying to solve this last night the answer hit me like a brick. The
Qtyped result ofU::operator*(Base)is conceptually the same as theBasetyped result ofoperator*(U,Base), even though they are being represented by different Types. All I need to do is provide a constructor forBase ( const Q & )that accepts type Q.This makes my example compile. Now to see if I can actually write the desired constructor in the real version (where a
Baseis actually aBase<Q,...>and theQwe accept is aQ<Base,...>).Unfortunately, presenting a simplified abstract example of the problem made it harder to spot this solution, so I had quite an advantage. Thanks go out to all who chipped in with ideas / comments and answers.