Given the following code:
template<typename T>
class A
{
public:
T t;
};
class B
{
public:
void foo(int i) {}
template<typename T>
void foo(A<T>& a) {}
};
int main()
{
A<int> a;
B b;
b.foo(a );
b.foo(a.t);
}
This compiles and works fine; the correct overloaded versions of B::foo() are chosen and called for a and a.t.
Now I introduce a new class C which derives from B and move the template version of ::foo() out of B and into C:
template<typename T>
class A
{
public:
T t;
};
class B
{
public:
void foo(int i) {}
};
class C: public B
{
public:
template<typename T>
void foo(A<T>& a) {}
};
int main()
{
A<int> a;
C c;
c.foo(a ); // Fine
c.foo(a.t); // Error
}
And now the code won’t compile anymore. Visual Studio 2005 is stating:
error C2784: 'void C::foo(A<T> &)' : could not deduce template argument for 'A<T> &' from 'int'
In fact, calling C::foo() with any int value results in this error. It almost seems like the method overload for int is being hidden by the template overload.
Why is this happening? Is it some issue with Visual Studio 2005’s compiler? Unfortunately, I cannot test it on any other compiler right now.
Any information is appreciated.
Exactly! You need to add a using declaration to class C:
When you declare a member function in a derived class, all member functions in the base class with the same name are hidden. See §3.3.10/3 of ISO/IEC 14882:2011: