2

下一个代码:

#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 中按预期工作。

4

1 回答 1

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>();
}
于 2013-08-14T08:28:03.567 回答