gpt4 book ai didi

c++ - 如何使用 type_traits 或模板函数特化来整合模板方法

转载 作者:行者123 更新时间:2023-11-28 06:51:01 25 4
gpt4 key购买 nike

我正在尝试从一个类似于下面所示的类中合并许多非常相似的函数方法,我认为有效实现它的最佳方法是通过使用模板结合模板函数特化或替代类型特征。我是模板特化和类型特征的新手,但我了解基本概念,这就是为什么我要求提供一些有关细节的指导。无论如何,作为起点,我的类是一个智能缓冲区类,它具有许多与下面列出的方法签名相似的方法签名。

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 方法,我将以下方法放在一起。我也为写方法做了类似的事情。这些显示在编译中 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 位值参数)。任何解决这个问题的帮助将不胜感激。

最佳答案

你可以使用类似的东西:

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);

关于c++ - 如何使用 type_traits 或模板函数特化来整合模板方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23964955/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com