Let's start with some code.
class intClass {
public:
virtual ~intClass() = default;
virtual int sum(int a, int b) const = 0;
};
class doubleClass {
public:
virtual ~doubleClass() = default;
virtual double sum(double a, double b) const = 0;
};
template<typename T, typename C>
class sumClass : public C {
public:
T sum(T a, T b) const override {
return a + b;
}
};
int main() {
sumClass<int, intClass> intSum;
sumClass<double, doubleClass> doubleSum;
return 0;
}
Assume that intClass
and doubleClass
cannot be changed.
I'd like to remove the template parameter T
from sumClass
.
Is it possible to deduce T
based on the signature of the sum
function in the base class instead?
We can use up to C++20.
Overall, I want my main
function to look like this:
int main() {
sumClass<intClass> intSum;
sumClass<doubleClass> doubleSum;
return 0;
}
You can create a trait to deduce the expected type:
template <typename Sig>
struct sumTrait;
template <typename T, typename C>
struct sumTrait<T (C::*)(T, T) const>
{
using type = T;
};
Then use that trait:
template<typename C>
class sumClass : public C {
using T = typename sumTrait<decltype(&C::sum)>::type;
public:
T sum(T a, T b) const override {
return a + b;
}
};