默认模板参数编译器错误

时间:2013-08-14 08:12:04

标签: 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
{
        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中按预期工作。

1 个答案:

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