C++ 默认模板参数编译器错误
下一个代码:C++ 默认模板参数编译器错误,c++,visual-studio-2010,visual-studio,visual-studio-2012,C++,Visual Studio 2010,Visual Studio,Visual Studio 2012,下一个代码: #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 {
#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>();
}
这是一个已知的编译器错误吗
请注意,它在VS2013中可以正常工作。您的编译器可能会感到困惑,因为您有一个函数模板声明,后面跟一些看起来像函数模板部分专门化的东西。GCC正确地拒绝您的代码 准确地说,这就是问题所在:
template<typename T>
void f<T>(T t) { .... }
// ^^^
模板
空f(T){…}
// ^^^
如果您真的想将声明和定义分开,您需要
template<typename T>
void f(T t) { .... }
模板
空f(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>();
}
#包括
#包括
结构A{};//一如既往
结构B{};//一如既往
结构C{};//一如既往
模板
void f(T=T())
{
std::我是否可以更正代码并编辑问题,但问题仍然存在于VS@Felics的所有3个版本中。我澄清了我的答案。问题不是无名参数,而是函数模板定义错误。我将代码更改为使用gcc编译(它具有预期的输出!),但对于Visual Studio 2008、2010、2012,它没有预期的输出。另一个错误似乎是编译器接受了初始代码(定义上没有和有f)@Felics头可以被其他头包含,所以可能是typeinfo
被iostream
包含。你不能相信这一点。但是f
的事情看起来确实很奇怪。小的添加-如果声明f在main之后,那么它将按预期工作(在VS2010上)。对我来说,COMDAT折叠不正确-你能发布编译器为此生成的程序集吗?
#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>();
}