//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()
}