GCC/VS2008: Different behaviour of function call when templated base class is derived from itself
c++, gcc, inheritance, templates, visual-studio-2008
Solution
After some digging through N3035, I found this in section 14.9.2.1.4:
If P is a class and P has the form simple-template-id, then the transformed A can be a derived class of the deduced A. Likewise, if P is a pointer to a class of the form simple-template-id, the transformed A can be a pointer to a derived class pointed to by the deduced A.
However in 14.9.2.1.5, it says:
These alternatives are considered only if type deduction would otherwise fail. If they yield more than one possible deduced A, the type deduction fails.
Which is the case: both `A<1>` and `A<0>` are considered base classes for `B`.
I guess this means a no for Visual Studio (at least, if the current standard says the same: exercise for the reader).
Problem
The following code works with Visual Studio 2008 but not with GCC/G++ 4.3.4 20090804. Which behaviour is - according to the C++ standard - correct? ``` template <int N> struct A : A<N-1> {}; template <> struct A<0> {}; struct B : A<1> {}; template <int N> void Func(const A<N> &a) {} int main() { A<1> a; //is derived from A<0> Func(a); //vs2008: ok, g++: ok //Comeau: ok B b; //is derived from A<1> Func(b); //vs2008: ok, g++: error, no matching function for call to Func(B&) //Comeau: error: no instance of function template "Func" matches the // argument list. The argument types that you used are: (B). return 0; } ``` If I overload Func() with ``` void Func(const A<0> &a) { std::cout << '0'; } void Func(const A<1> &a) { std::cout << '1'; } ``` always the latter one is called (as expected). So I would also expect the templated function to be called with N=1 because A<1> is direct base of B. Is this assumption really wrong?