Mircea Ispas
Mircea Ispas

Reputation: 20780

Default template arguments compiler bug

Next code:

#include <typeinfo>
#include <iostream>

struct A
{
    A() : _m('a'){ std::cout << "A()" << std::endl; }
        void f(){ std::cout << "A::f() " << _m << std::endl; }

        char _m;
};

struct B
{
        B() : _m('b'){ std::cout << "B()" << std::endl; }
        void f(){ std::cout << "B::f() " << _m << std::endl; }

        char _m;
};

struct C
{
        C() : _m('c'){ std::cout << "C()" << std::endl; }
        void f(){ std::cout << "C::f() " << _m << std::endl; }

        char _m;
};

template<typename T>
void f(T t = T());

template<typename T>
void f(T t)
{
        std::cout << typeid(t).name() << std::endl;

        t.f();
}

int main()
{
        f<A>();
        f<B>();
        f<C>();
}

Has this output when using VS2008, VS2010 and VS2012:

A()
struct A
A::f() a
A()
struct B
B::f() a
A()
struct C
C::f() a

Is this a known compiler bug?

Please note that it works as expected in VS2013.

Upvotes: 2

Views: 146

Answers (1)

juanchopanza
juanchopanza

Reputation: 227390

Your compiler might be confused because you have a function template declaration, followed by something that looks like a function template partial specialization. GCC correctly rejects your code.

To be precise, this is the problem:

template<typename T>
void f<T>(T t) { .... }
//    ^^^

If you really want to separate declaration and definition, you would need

template<typename T>
void f(T t) { .... }

This would be a well-formed version of your program:

#include <iostream>
#include <typeinfo>

struct A {}; // as before
struct B {}; // as before
struct C {}; // as before

template<typename T>
void f(T t = T())
{ 
    std::cout << typeid( t ).name() << std::endl;
    t.f();
}

int main()
{
    f<A>();
    f<B>();
    f<C>();
}

Upvotes: 1

Related Questions