I am having an issue getting template specialization of member methods to compile correctly. I have read all the suggested articles and, in every one, the class itself is templated. In my case, I don't have a templated class, just simple a templated method.
Here is an example:
//In Test.h
class Test {
public:
template <typename T>
void foo(const T& v) {
//Do something generic with T
}
};
//In Test.cpp
template <>
void Test::foo<unsigned int>(const unsigned int& v) {
//Do something specific with unsigned int
}
Based upon this article multiple definition of template specialization when using different objects I have put the specializations in my CPP file. However, this results in the specialized function NOT being called when I do something like the following:
#include "Test.h"
int main() {
Test t;
unsigned int a;
t.foo(a);
}
However, If I put the specializations in the .h file, then I get a ton of "duplicate definitions of" errors.
What is the correct way to go about this?
Thanks!
EDIT
Here is a snippet of my actual code
#ifndef BYTEARRAY_H_
#define BYTEARRAY_H_
#include <memory>
#include <limits.h>
#include <string.h>
#include <iterator>
namespace tw {
class ByteArray {
public:
//...
size_t append(const void* source, size_t sourceSize);
template <typename T>
inline size_t append(const T& v) {
static_assert(std::is_trivially_copyable<T>::value, "T must be trivially copyable (i.e. via memcpy) to use ByteArray::append<T>");
return append(reinterpret_cast<const void*>(&v), sizeof(T));
}
private:
void _deepCopy();
//-- Member Data --
/**
* @brief Total number of bytes allocated and pointed to by _memory
*/
size_t _capacity;
/**
* @brief Current "virtual" size of the array
*/
struct {
size_t _length : (CHAR_BIT * sizeof(size_t)) - 1;
bool _isStatic : 1;
};
/**
* @brief Shared/smart pointer to the underlying, allocated array of bytes
*/
std::shared_ptr<uint8_t[]> _memory;
/**
* @brief A small amount of memory for use when capacity() < sizeof(size_t)
* rather than allocated memory on the heap for _memory
*/
uint8_t _memoryDirect[sizeof(size_t)];
};
template <>
size_t ByteArray::append<ByteArray>(const ByteArray& v) {
return append(v.data().get(), v.length());
}
template <>
size_t ByteArray::append<uint8_t>(const uint8_t& v) {
ASSERT(!isFull());
dataMutable().get()[_length++] = v;
return 1;
}
} /* namespace tw */
#endif /* BYTEARRAY_H_ */