Consider the following situation, where a base class prescribes a function that can be reimplemented in a derived class:
template<typename Impl>
class Base {
public:
void f(double& value, double param)
{ value = 0.0; }
};
class Implementation : public Base<Implementation> {
public:
void f(double& value, double param)
{ value = param; }
};
int main()
{
Implementation imp;
double value = 0.0;
imp.f(value, 1.0);
}
Suppose that I want to change the signature of the function f in the base class to double f(double param) and to use that for Base and derived classes. I want to perform this change without breaking immediately all implementation classes. Instead, a provider of an implementation class should get a deprecation warning. I came up with the following:
template<typename Impl>
class Base {
public:
double f(double param) __attribute__ ((deprecated))
{
double v = 0.0;
static_cast<Impl*>(this)->f(v, param);
return v;
}
void f(double& value, double param)
{ value = 0.0; }
};
// class Implementation as before
int main()
{
Implementation imp;
double value = imp.f(1.0);
}
As a result, the Base version of f should only be called if f isn't reimplemented in Implementation with the new signature, yielding the desired deprecation warning.
Obviously, this doesn't compile because the definition of f in Implementation shadows the f in Base:
error: no matching function for call to ‘Implementation::f(double)’
double value = imp.f(1.0);
One solution would be to add using:
class Implementation : public Base<Implementation> {
public:
using Base<Implementation>::f;
void f(double& value, double param)
{ value = param; }
};
That would force the provider of Implementation to change immediately his code which is exactly what should be avoided in the first place. Another possibility would be to change the name f in the new signature. I also would like to avoid this since f has a really good name in my real use case.
So my question is: Can I perform the signature change
- such that providers of
Implementationget a deprecation warning, but their code is not broken immediately, i.e., without changes toImplementation, and - without having to rename
f?