I have the following template method:
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);
}
But I get those strange linker errors:
/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
How can I specialize this member function?
EDIT
This approach works:
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);
}
};
or with inline
s or specializing it outside the class with 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);
}
You may define a template member function outside of its class template definition. When you call a member function of a class template specialization, the compiler will use the template arguments that you used to generate the class template.
Template in C++is a feature. We write code once and use it for any data type including user defined data types. For example, sort() can be written and used to sort any data type items. A class stack can be created that can be used as a stack of any data type.
To do so, we can use a function template specialization (sometimes called a full or explicit function template specialization) to create a specialized version of the print() function for type double.
Explicit (full) specializationAllows customizing the template code for a given set of template arguments.
As Igor mentioned, you can implement the generic version in the header file, and then the specialization in the cpp file, for example:
// MyStruct.h
struct MyStruct {
// ...
template <typename T>
void readField(std::istream& in, T& data) {
read(in, data);
data = ntohl(data);
}
};
Then in the cpp file you can implement the specialization, for example:
// MyStruct.cpp
template <>
void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data) {
read(in, data);
}
Update: After reading the comments, the specialization can also be in the same header file as the primary template, but not within the struct, for example (I verified this by compiling and running a similar example without error):
// 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With