如何专门化模板成员函数?
How to specialize template member 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);
}
但是我遇到了那些奇怪的链接器错误:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/exception:62:
multiple definition of `void MyStruct::readField(std::basic_istream >&, unsigned
char&)'
../Lib/obj/MyStruct.o:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/exception:62:
first defined here collect2: ld returned 1 exit status make: ***
[Lib] Error 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);
}
};
或 inline
s 或在 class 之外用 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);
}
您可以inline
特化以避免多重定义。
template<>
inline void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data)
{
read(in, data);
}
为了完整起见,您还有另一个选择是在 .cpp 文件中创建一个实现,然后通过 header.
导出该实现
//MyStruct.h
#ifdef MYSTRUCT_EXPORTS
#ifdef __GNUC__
#ifndef __linux__
#define MYSTRUCT_API __attribute__ ((dllexport))
#else
#define MYSTRUCT_API __attribute__ ((visibility ("default")))
#endif
#else
#define MYSTRUCT_API __declspec(dllexport)
#endif
#else
#ifdef __GNUC__
#ifndef __linux__
#define MYSTRUCT_API __attribute__ ((dllimport))
#else
#define MYSTRUCT_API __attribute__ ((visibility ("default")))
#endif
#else
#define MYSTRUCT_API __declspec(dllimport)
#endif
#endif
template<>
void MYSTRUCT_API MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data);
//MyStruct.cpp
template<>
void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data)
{
read(in, data);
}
正如Igor所说,你可以在头文件中实现通用版本,然后在cpp文件中实现特化,例如:
// MyStruct.h
struct MyStruct {
// ...
template <typename T>
void readField(std::istream& in, T& data) {
read(in, data);
data = ntohl(data);
}
};
然后在cpp文件中可以实现特化,例如:
// MyStruct.cpp
template <>
void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data) {
read(in, data);
}
更新:阅读评论后,特化也可以在与主模板相同的头文件中,但不在结构中,例如(我通过编译和运行一个类似的例子验证了这一点没有错误):
// 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
我有以下模板方法:
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);
}
但是我遇到了那些奇怪的链接器错误:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/exception:62: multiple definition of `void MyStruct::readField(std::basic_istream >&, unsigned char&)' ../Lib/obj/MyStruct.o:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/exception:62: first defined here collect2: ld returned 1 exit status make: *** [Lib] Error 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);
}
};
或 inline
s 或在 class 之外用 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);
}
您可以inline
特化以避免多重定义。
template<>
inline void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data)
{
read(in, data);
}
为了完整起见,您还有另一个选择是在 .cpp 文件中创建一个实现,然后通过 header.
导出该实现//MyStruct.h
#ifdef MYSTRUCT_EXPORTS
#ifdef __GNUC__
#ifndef __linux__
#define MYSTRUCT_API __attribute__ ((dllexport))
#else
#define MYSTRUCT_API __attribute__ ((visibility ("default")))
#endif
#else
#define MYSTRUCT_API __declspec(dllexport)
#endif
#else
#ifdef __GNUC__
#ifndef __linux__
#define MYSTRUCT_API __attribute__ ((dllimport))
#else
#define MYSTRUCT_API __attribute__ ((visibility ("default")))
#endif
#else
#define MYSTRUCT_API __declspec(dllimport)
#endif
#endif
template<>
void MYSTRUCT_API MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data);
//MyStruct.cpp
template<>
void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data)
{
read(in, data);
}
正如Igor所说,你可以在头文件中实现通用版本,然后在cpp文件中实现特化,例如:
// MyStruct.h
struct MyStruct {
// ...
template <typename T>
void readField(std::istream& in, T& data) {
read(in, data);
data = ntohl(data);
}
};
然后在cpp文件中可以实现特化,例如:
// MyStruct.cpp
template <>
void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data) {
read(in, data);
}
更新:阅读评论后,特化也可以在与主模板相同的头文件中,但不在结构中,例如(我通过编译和运行一个类似的例子验证了这一点没有错误):
// 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