开发者

GCC/VS2008: Different behaviour of function call when templated base class is derived from itself

The following code works with Visual Studio 2008 but开发者_如何学Go 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?


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).


In ISO/IEC 14882 it's nearly the same (14.8.2.1):

  • If P is a class, and P has the form template-id, then A can be a derived class of the deduced A. Likewise, if P is a pointer to a class of the form template-id, A can be a pointer to a derived class pointed to by the deduced A.

These altenatives are considered only if type deduction would otherwise fail. If they yield more than one possible deduced A, the type deduction fails.

So I agree with Jan. Anybody here who does not?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜