I have heard that C++ class member function templates can\'t be virtual. Is this true?
If they can be virtual, what is an example of a scenario in which one would
There is a workaround for 'virtual template method' if set of types for the template method is known in advance.
To show the idea, in the example below only two types are used (int
and double
).
There, a 'virtual' template method (Base::Method
) calls corresponding virtual method (one of Base::VMethod
) which, in turn, calls template method implementation (Impl::TMethod
).
One only needs to implement template method TMethod
in derived implementations (AImpl
, BImpl
) and use Derived<*Impl>
.
class Base
{
public:
virtual ~Base()
{
}
template
T Method(T t)
{
return VMethod(t);
}
private:
virtual int VMethod(int t) = 0;
virtual double VMethod(double t) = 0;
};
template
class Derived : public Impl
{
public:
template
Derived(TArgs&&... args)
: Impl(std::forward(args)...)
{
}
private:
int VMethod(int t) final
{
return Impl::TMethod(t);
}
double VMethod(double t) final
{
return Impl::TMethod(t);
}
};
class AImpl : public Base
{
protected:
AImpl(int p)
: i(p)
{
}
template
T TMethod(T t)
{
return t - i;
}
private:
int i;
};
using A = Derived;
class BImpl : public Base
{
protected:
BImpl(int p)
: i(p)
{
}
template
T TMethod(T t)
{
return t + i;
}
private:
int i;
};
using B = Derived;
int main(int argc, const char* argv[])
{
A a(1);
B b(1);
Base* base = nullptr;
base = &a;
std::cout << base->Method(1) << std::endl;
std::cout << base->Method(2.0) << std::endl;
base = &b;
std::cout << base->Method(1) << std::endl;
std::cout << base->Method(2.0) << std::endl;
}
Output:
0
1
2
3
NB:
Base::Method
is actually surplus for real code (VMethod
can be made public and used directly).
I added it so it looks like as an actual 'virtual' template method.