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
Implementation
get a deprecation warning, but their code is not broken immediately, i.e., without changes toImplementation
, and - without having to rename
f
?