In a templated class, can we check a member function's signature and define different compilation behaviors for different subclasses? To be more specific, consider the following simple example:
template <typename T>
class Foo {
// ingore all other functions
virtual std::shared_ptr<T> do_something(int a) {
return std::make_shared<T>(a);
}
};
This should just work fine with the T1
class:
class T1 {
T1(int a) {
// implememntation
}
// ingore all other functions
};
// Foo<T1> would just work
However, it will fail the compilation with T2
because Foo
's do_something
function is clearly implemented to call T
's constructor with one argument only:
class T2 {
T2(int a, int b) {
// implememntation
}
// ingore all other functions
};
// Foo<T2> would fail to compile
So the question is, can we rework on Foo
to let it work for both T1
and T2
, in the way that, for T1
and classes whose constructor takes one int
argument, it will compile with a default implementation, whereas for T2
and classes whose constructors are different, it will compile with a virtual function and enforce subclass to implement it with override
. Somewhat like below:
Template <typename T>
class Foo {
// ingore all other functions
/* if T's signature takes one int input only
* compile like the below
*/
virtual std::shared_ptr<T> do_something(int x) {
return std::make_shared<T>(x);
}
/* if T's signature is different
* compile like the below and let the subclass implement it
*/
virtual std::shared_ptr<T> do_something(int x) = 0;
}
Is this possible without using any 3rd-party library? It's acceptable if we have to use macros/preprocessors.
It is also acceptable if there must be one function do_something
there but for the case of mismatched signature, it just raises runtime exception, something like:
Template <typename T>
class Foo {
// ingore all other functions
virtual std::shared_ptr<T> do_something(int x) {
/* if T's signature takes one int input only
* compile like the below
*/
// return std::make_shared<T>(x);
/* if T's signature is different
* compile like the below and let the subclass implement it
*/
// std::throws...
}
}