c++ - 与 C++ 模板的预处理器式连接?

标签 c++ templates

为了这个问题,假设我正在将 betoh16() 等实现为名为 OpSys 的 C++ 类中的方法。这样做时,我注意到所有 12 个左右的函数大部分都是相同的,我不想重复这么多源代码。

我可以选择使用预处理器执行以下操作...

typedef uint16_t U16;
typedef uint32_t U32;
typedef uint64_t U64;

#define BETOH_XX(nbits)                        \
  U##nbits OpSys::betoh##nbits, U##nbits val)  \
  {                                            \
    if (CPU_IS_BIG_ENDIAN)                     \
      return val;                              \
                                               \
    return bswap##nbits(val);                  \
  }

BETOH_XX(16)
BETOH_XX(32)
BETOH_XX(64)

...但我想知道是否有某种方法可以用模板完成同样的事情,我的调用看起来像

U16 hval = betoh<16>(beval);

我在 SO 上看到了一些关于 templates with constant values 的其他问题,但似乎没有将该模板化值连接到某些相邻文本。

这可能吗?

最佳答案

我认为连接任意模板值以形成新标识符是不可能的(或者应该是,它会破坏提供的额外安全模板)。但是,(如评论中所述)可以为您的特定示例存档类似的内容。

获取所需的语法

U16 hval = betoh<16>(beval);

首先需要从其位大小中获取其中一种固定大小的整数类型。在这个视频中http://www.youtube.com/watch?v=MvFj8qo1iuA , Andrei Alexandrescu 在 19:45 左右展示了一个很好的方法。基本上,您只需声明一个带有 typedef 类型成员的模板结构,并仅针对那些可用的类型专门化它,而对所有其他类型保持未定义状态:

template <size_t bitsize> struct uint_bits;

template<> struct uint_bits<8>{typedef uint8_t type;};
template<> struct uint_bits<16>{typedef uint16_t type;};
template<> struct uint_bits<32>{typedef uint32_t type;};

有了这个,您需要做的就是模板 betoh 和 bswap:

template <size_t bitsize>
typename uint_bits<bitsize>::type bswap(typename uint_bits<bitsize>::type value)
{
    typename uint_bits<bitsize>::type ret_val=0;
    for(size_t b=0;b<sizeof(value);++b)
    {
        ret_val<<=8;
        ret_val|=(value&0xff);
        value>>=8;
    }
    return ret_val;
}

template <size_t bitsize>
typename uint_bits<bitsize>::type betoh(typename uint_bits<bitsize>::type value)
{
    if(CPU_IS_BIG_ENDIAN)
        return value;

    return bswap<bitsize>(value);
}

这可以通过明确说明位数来使用,恕我直言,有点冗长,使实现复杂化并将函数限制为已知类型,尽管它们可以使用任意无符号整数:

template <typename T>
T bswap(T value)
{
    T ret_val=0;
    for(size_t b=0;b<sizeof(value);++b)
    {
        ret_val<<=8;
        ret_val|=(value&0xff);
        value>>=8;
    }
    return ret_val;
}

template <typename T>
T betoh(T value)
{
    if(CPU_IS_BIG_ENDIAN)
        return value;

    return bswap(value);
}

这不需要 uint_bits 结构,并且允许将上述调用重写为简单

U16 hval = betoh(beval);

我不确定这些是否实用和/或有效,所以 ;-)。

关于c++ - 与 C++ 模板的预处理器式连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24348454/

相关文章:

c++ - 继承基类的所有内容

c++ - netbeans中多重定义的问题

c++ - 获取 scons 以生成新的内部版本号

c++ - 检测 C++ lambda 是否可以转换为函数指针

python - 如何更改 django wagtail 的管理 Logo

c++ - 仅更改一个成员函数的类模板特化

c++ - 录制屏幕时不会出现奇怪的 MFC/GDI 行为(空白图像)

c++ - unique_ptr 作为模板参数

C++:auto_ptr + 前向声明?

c++ - 带有 const 模板和 const 引用模板参数的 std::map