//virtual void func(int a) {}
// replace above line with this and it works
Replace the above line and the code compile, doesn't works.
Or, better, works but not as you expect.
The problem is that virtual
functions and template
functions doesn't mix very well.
So you can't make a template function that directly override a virtual function: if you define func()
as a null virtual function
virtual void func(int a) = 0;
the base A
class, and all derived classes, become not-instantiable until you don't define an effective virtual
func()
function.
Defining
virtual void func(int a) {}
the base A
class, and all derivate, isn't not-instantiable anymore a you don't need anymore a redefinition of the virtual function.
But the template
func()
version is not related with virtual function.
When you call b.func(2)
in main()
, it's the template
, not the virtual
func()
inherited from A
, that is called. It's because the template
func()
"hide" the func()
inherited virtual
version.
You can "un-hide" the virtual
func()
version in B
adding, in the body of B
definition
using A::func;
This way, calling b.func(2);
in main()
, the virtual
version inherited by A
is called and the template specialization of func()
, so the std::cout <<"hello 2" << std::endl;
instruction, ins't executed anymore.
Now... if I understand correctly, you want a template
func()
function that, in case of T == int
join the virtual specialization.
The only way I see is define the virtual
override
in B
void func (int a) override // override, so necessarily virtual
{ std::cout <<"hello 2" << std::endl; }
and call it from the template
specialization
template <>
void B::func<int> (int a)
{ func(a); } // call the virtual override version
The following is a full compiling example
#include <iostream>
struct A
{ virtual void func(int a) = 0; };
struct B : public A
{
void func (int a) override
{ std::cout <<"hello 2" << std::endl; }
template<typename T>
void func (T t)
{ std::cout << "hello" << std::endl; }
};
template <>
void B::func<int> (int a)
{ func(a); }
int main ()
{
B{}.func(2); // call directly virtual func()
B{}.func<int>(2); // call template func() specialization that call virtual func()
}
Member function templates cannot be declared virtual.
– Stack Danny