【发布时间】:2021-05-07 14:25:13
【问题描述】:
我在获取成员方法的模板特化以正确编译时遇到问题。我已经阅读了所有建议的文章,并且在每一篇文章中,课程本身都是模板化的。就我而言,我没有模板类,只是一个简单的模板方法。
这是一个例子:
//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
}
根据这篇文章multiple definition of template specialization when using different objects,我已将专业化放在我的 CPP 文件中。但是,这会导致当我执行以下操作时不会调用专用函数:
#include "Test.h"
int main() {
Test t;
unsigned int a;
t.foo(a);
}
但是,如果我将专业化放在 .h 文件中,则会收到大量“重复定义”错误。
解决这个问题的正确方法是什么?
谢谢!
编辑
这是我的实际代码的 sn-p
#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_ */
【问题讨论】:
-
你必须在标题中声明特化。
-
错字? “我已将专业化放在我的 CPP 中......发生了一些事情......” vs “但是,如果我将专业化放在 CPP 文件中,......还有别的......”
-
@largest_prime_is_463035818 是的,这是一个错字。对于那个很抱歉。当我将我的特化移动到头文件时,我编译得很好,但是链接器会抛出“多重定义”错误。
-
你需要标题保护,但如果你只包含一次,就像这里的例子一样,这实际上不应该发生
-
完全专业化不再是模板,因此不再隐含
inline。您必须将它们标记为inline。
标签: c++ templates template-specialization