【发布时间】:2014-05-30 23:50:02
【问题描述】:
我正在尝试从类似于下面显示的类中整合许多非常相似的函数方法,我认为有效实现这一点的最佳方法是通过使用模板与模板函数专业化相结合,或者类型特征。我是模板专业化和类型特征的新手,但我了解基本概念,这就是为什么我要求有关细节的一些指导。无论如何,作为起点,我的类是一个智能缓冲区类,它有许多与下面列出的方法签名相似的方法签名。
class OldSafeBuffer {
public:
intmax_t writeAt(const intmax_t& rIndex, const uint32_t val32);
intmax_t writeAt(const intmax_t& rIndex, const int32_t val32);
intmax_t readFrom(const intmax_t& rIndex, uint32_t& rVal32);
intmax_t readFrom(const intmax_t& rIndex, int32_t& rVal32);
intmax_t writeAt(const intmax_t& rIndex, const uint16_t val16);
intmax_t writeAt(const intmax_t& rIndex, const int16_t val16);
intmax_t readFrom(const intmax_t& rIndex, uint16_t& rVal16);
intmax_t readFrom(const intmax_t& rIndex, int16_t& rVal16);
intmax_t read(uint32_t& rVal32);
intmax_t read(int32_t& rVal32);
intmax_t read(uint16_t& rVal16);
intmax_t read(int16_t& rVal16);
protected:
// Actual memory storage.
std::unique_ptr<char[]> mBuffer;
// Buffer length
intmax_t mBufferLength;
// Represents the largest byte offset referenced.
// Can be used to retrieve written length of buffer.
intmax_t mHighWaterMark;
// If set, caller wanted to pack data in network-byte-order.
bool mPackNBO;
// Set on construction, determines whether value needs to be byte-swapped.
bool mSwapNeeded;
// Used for file compatibility
intmax_t mPosition;
};
我认为这将是转换为使用模板函数的完美候选者,因为这些函数非常相似,而且我在每种方法中都有很多重复的代码。方法之间的区别主要是符号和 16 位或 32 位值参数的大小。
无论如何,为了巩固 readFrom 方法,我将以下方法放在一起。我也为 write 方法做了类似的事情。这些显示在编译live example。
/**
* Read value (signed or unsigned) from buffer at given byte offset.
*
* @param rIndex [in]
* @param rVal [out]
*
* @return BytesRead or -1 on error
*/
template <typename T>
inline intmax_t readFrom(const intmax_t& rIndex, T& rVal)
{
if ((rIndex + static_cast<intmax_t>(sizeof(T))) <= mBufferLength) {
T* pVal = (T *)&mBuffer[rIndex];
rVal = *pVal;
// @JC Partial Template Specialization for 16 bit entities?
if (sizeof(rVal) > sizeof(int16_t)) {
SWAP32(rVal);
} else {
SWAP16(rVal);
}
mPosition = rIndex + sizeof(T);
return sizeof(rVal);
}
return -1;
}
从我的评论中可以看出,我仍然需要知道“T& rVal”参数的大小,以便决定是对参数执行 SWAP32 还是 SWAP16。这就是为什么我认为 type_traits 可以派上用场,而不必进行运行时检查来比较参数的大小。
我认为我在正确的轨道上,但我不知道如何使用 type_traits 根据参数类型检查和做某些事情。我认为或者我可以使用模板方法专业化对 16 位参数执行特殊操作,但我认为这不会节省太多精力,因为我还必须专注于 16 位参数类型的有符号和无符号变体(假设非专用版本用于 32 位值参数)。任何解决此问题的帮助将不胜感激。
【问题讨论】:
标签: c++ templates template-specialization typetraits specialization