如何专门化模板成员函数?

Pat*_*ryk 3 c++ templates member-functions template-function

我有以下模板方法:

struct MyStruct
{
  // ...
  template<typename T>
  void readField(std::istream& in, T& data)
  {
      read(in, data);
      data = ntohl(data);
  }
};

template<>
void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data)
{
    read(in, data);
}
Run Code Online (Sandbox Code Playgroud)

但是我得到那些奇怪的链接器错误:

/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/exception:62:`void MyStruct :: readField的多个定义(std :: basic_istream>&,未签名的char&)'../Lib/obj/MyStruct.o:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../。 ./include/c++/4.4.7/exception:62:首先在这里定义collect2:ld返回1退出状态make:*** [lib]错误1

如何专门化该成员函数?

编辑

此方法有效:

struct MyStruct
{
  // ...
  template<typename T>
  void readField(std::istream& in, T& data)
  {
    read(in, data);
    data = ntohl(data);
  }

  void readField(std::istream& in, uint8_t& data)
  {
    read(in, data);
  } 
};
Run Code Online (Sandbox Code Playgroud)

或与inlines或在课外使用inline

struct MyStruct
{
  // ...
  template<typename T>
  void readField(std::istream& in, T& data)
  {
      read(in, data);
      data = ntohl(data);
  }
};

template<>
inline void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data)
{
    read(in, data);
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*cas 6

如Igor所述,您可以在头文件中实现通用版本,然后在cpp文件中实现专业化,例如:

// MyStruct.h

struct MyStruct {
  // ...
  template <typename T>
  void readField(std::istream& in, T& data) {
    read(in, data);
    data = ntohl(data);
  }
};
Run Code Online (Sandbox Code Playgroud)

然后,可以在cpp文件中实现专业化,例如:

// MyStruct.cpp

template <>
void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data) {
  read(in, data);
}
Run Code Online (Sandbox Code Playgroud)

更新:阅读注释后,专业化也可以与主模板位于相同的头文件中,但不在结构内(例如,我通过编译并运行类似的示例而没有错误地验证了这一点):

// MyStruct.h

struct MyStruct {
  // ...
  template <typename T>
  void readField(std::istream& in, T& data) {
    read(in, data);
    data = ntohl(data);
  }
};  

template <>
inline void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data) {
  read(in, data);
}

// End MyStruct.h
Run Code Online (Sandbox Code Playgroud)