Reputation: 20780
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
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