我正在尝试从类似于以下所示类的类中合并许多非常相似的函数方法,我认为有效实现此目的的最佳方法是通过使用模板,再结合使用模板功能专门化或类型特征。我是模板专业化和类型特征的新手,但是我了解基本概念,因此正要我就这些细节寻求一些指导。无论如何,我的类都是一个智能缓冲区类,它具有许多与下面列出的方法签名相似的方法签名。
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方法,我将以下方法放在一起。对于写方法,我也做了类似的事情。这些在编译实时示例中显示。
/**
* 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位值参数)。任何帮助弄清楚这一点将不胜感激。
您可以使用类似:
template<typename T, std::size_t N = sizeof(T)> struct Swap;
template<typename T> struct Swap<T, 1> {
void operator() (T&) const { /* Do nothing*/ }
};
template<typename T> struct Swap<T, 2> {
void operator() (T& val) const { SWAP16(val); }
};
template<typename T> struct Swap<T, 4> {
void operator() (T& val) const { SWAP32(val); }
};
然后调用它:
Swap<T>()(rVal);
因此,在上下文中:
if (sizeof(T) > sizeof(int16_t)) {
SWAP32(val);
} else {
SWAP16(val);
}
可以写成
Swap<T>()(val);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句