gpt4 book ai didi

c++ - 如何使用c++11/14来简化这个实现

转载 作者:搜寻专家 更新时间:2023-10-31 00:57:28 24 4
gpt4 key购买 nike

故事有点长,是整数的endian通用实现,原代码如下:

#ifdef _BIG_ENDIAN_
#define ENDIANUSHORT(src) (unsigned short)src
#define ENDIANULONG(src) (unsigned long)src
#define ENDIANUINT64(src) (unsigned long long)src
#else
#define ENDIANUSHORT(src) ((unsigned short)((((src)>>8)&0xff) |\
(((src)<<8)&0xff00)))

#define ENDIANULONG(src) ((unsigned long)((((src)>>24)&0xFF) |\
(((src)>> 8)&0xFF00) |\
(((src)<< 8)&0xFF0000) |\
(((src)<<24)&0xFF000000)))

#define ENDIANUINT64(src) ((unsigned long long)((((src)>>56)&0xFF) |\
(((src)>>40)&0xFF00) |\
(((src)>>24)&0xFF0000) |\
(((src)>> 8)&0xFF000000) |\
(((src)<< 8)&0xFF00000000LL) |\
(((src)<<24)&0xFF0000000000LL) |\
(((src)<<40)&0xFF000000000000LL) |\
(((src)<<56)&0xFF00000000000000LL)))
#endif //_BIG_ENDIAN_

template<
typename T,
typename std::enable_if<std::numeric_limits<T>::is_integer>::type* = nullptr>
T _endian(T& t) {
if (sizeof(T) == 2)
return ENDIANUSHORT(t);
else if (sizeof(T) == 4)
return ENDIANULONG(t);
else if (sizeof(T) == 8)
return ENDIANUINT64(t);

return t;
}

template<typename T>
void endian(T& t) { t = _endian(t); }

int main()
{
long lv = 123;
endian(lv);
......
}

它运行良好,但在 MSVC 中有如下警告:

warning C4293: '>>': shift count negative or too big, undefined behavior

然后细化为:将 T _endian(T& t) 定义替换为以下代码:

static int64_t _endian(int64_t t) {
return ENDIANUINT64(t);
}

static uint64_t _endian(uint64_t t) {
return ENDIANUINT64(t);
}

static int32_t _endian(int32_t t) {
return ENDIANULONG(t);
}

static uint32_t _endian(uint32_t t) {
return ENDIANULONG(t);
}

static int16_t _endian(int16_t t) {
return ENDIANUSHORT(t);
}

static uint16_t _endian(uint16_t t) {
return ENDIANUSHORT(t);
}

static int8_t _endian(int8_t t) {
return t;
}

static uint8_t _endian(uint8_t t) {
return t;
}

现在没有警告,但我认为有两个缺点:

  1. 功能实现乏味、冗余且不简洁。
  2. 可能有些情况没有涵盖

我认为 C++11/14 可以提供一个优雅而简短的实现来完成它,你有什么想法吗?

谢谢。

最佳答案

您本身不需要 c++11/14。你需要做的是

  1. 用内联函数替换那些宏。这不仅更符合 c++sy,还有助于下一步。
  2. 使所述内联函数成为特征中的 static constexpr 成员类(class)。接受整数的 size_t 作为模板参数。
  3. 根据特征类实现模板。

代码:

template<std::size_t> struct EndianTraits;

template<>
struct EndianTraits<2u>
{
using type = std::uint16_t;
#ifdef _BIG_ENDIAN_
constexpr static type ToEndian(type val) { return val; }
#else
constexpr static type ToEndian(type val) { return ((((val)>>8)&0xff) |
(((val)<<8)&0xff00))); }
#endif
};

template<typename T,
typename = std::enable_if<std::numeric_limits<T>::is_integer>::type>
T Endian(T t) {
using type = EndianTraits<sizeof(T)>::type;
return EndianTraits<sizeof(T)>::ToEndian(static_cast<type>(t));
}

关于c++ - 如何使用c++11/14来简化这个实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37375658/

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