模板化成员函数的特化 class

specialization of member function of templated class

有:

以下代码的结果是什么?

foo.h

#include <iostream>

template<class _Tp>
struct Foo
{
   void print() { std::cout << "foo\n"; }
};

foo.cxx

#include "foo.h"

template<>
void Foo<int>::print()
{
   std::cout << "foo<int>\n";
}

main.cxx

#include "foo.h"

int main()
{
   Foo<double>().print();
   Foo<int>().print();
   return 0;
 }

结果不同:

  1. 当被 MSVC 编译时,

    foo
    foo
    
  2. g++编译时,

    foo
    foo<int>
    

无论编译器如何,我都想得到第二个结果。我还应该做什么才能实现?如果可能的话,你能给我一个关于底层标准或机制的解释吗?谢谢!

您的程序有未定义的行为。

Foo<int>::print() 有两种实现方式——从 class 模板定义中获得的内联定义和 foo.cxx 中的非内联定义。编译器可以自由选择。

不需要编译器将其诊断为问题。他们中的许多人(显然包括 g++ 和 MSVC)选择这条路线来定义 class 模板及其成员函数。

为确保两个编译器都选择 foo.cxx 中的实现,请在 foo.h 中声明函数。

#include <iostream>

template<class _Tp>
struct Foo
{
   void print() { std::cout << "foo\n"; }
};

template<> void Foo<int>::print();

是兴趣。我知道模板是在编译时解释的,而不是 link 时间。所以,在我看来,专业化模板应该在每个 cpp 文件中实现。你的 g++ 版本是多少?

如果 foo.h 如下所示,则两个编译器产生相同的结果。但是不知道为什么。

#include <iostream>


template<class _Tp>
struct Foo
{
   void print();
};

template<class _Tp>
void Foo<_Tp>::print()
{
   std::cout << "foo\n";
}

template<> void Foo<int>::print();