下一个代码:
#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>();
}
使用VS2008,VS2010和VS2012时有此输出:
A()
struct A
A::f() a
A()
struct B
B::f() a
A()
struct C
C::f() a
这是一个已知的编译器错误吗?
请注意,它在VS2013中按预期工作。
答案 0 :(得分:1)
您的编译器可能会混淆,因为您有一个函数模板声明,后跟看起来的内容,就像函数模板部分特化一样。 GCC正确拒绝您的代码。
准确地说,这就是问题所在:
template<typename T>
void f<T>(T t) { .... }
// ^^^
如果你真的想要分离声明和定义,你需要
template<typename T>
void f(T t) { .... }
这将是您的计划的一个格式良好的版本:
#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>();
}