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>();
}