繁体   English   中英

在编译时排除功能模板的一部分

[英]Exclude part of function template during compile time

请考虑以下代码。 它是一个功能模板,根据其位宽在类型T上进行操作。 实际的代码更为复杂,但这并不相关:

template <typename T> T MyFunc(T t)
{
   constexpr const uint8_t typeBitCount = sizeof(T)*8;

   // more code here that works fine for all widths

   if (typeBitCount >= 32)
   {
      if (...)
      {
         return t >> 16; // warning right shift count >= width of type
      }

      if (typeBitCount >= 64)
      {
         if (...)
         {
            return t >> 32; // warning right shift count >= width of type
         }
      }
   }
}

我也使用8位类型。 在这种情况下,我会收到警告(请参阅注释行)。 不幸的是,即使使用constexpr C ++也无法在编译期间评估if条件。 我可能可以抑制这些警告,但对我来说似乎很客气。 我希望在编译时排除有问题的代码。

如何解决这个问题(可能不会零碎地编写代码,也不会产生冗余)?

我正在使用GCC 5.4.0。

我会计算出有问题的班次,以便:

  • 当要执行移位时,它具有所需的值32,
  • 如果不应该执行,则它的值很小0:

     .... constexpr uint8_t shift2 = (typeBitCount >= 64) ? 32 : 0; .... if (typeBitCount >= 64) { if (...) { return t >> shift2; } } .... 

您可以使用类似于以下答案的部分模板专用化来使用函子来实现取决于类型大小的功能:

// Base implementation for unsupported size and type.
template <typename T, size_t TSize>
class MyFuncImpl;

// 32-bit specialization.
template <typename T>
struct MyFuncImpl<T, 4>
{
    T operator()(const T t) const
    {
        return t >> 16;
    }
};

// 64-bit specialization.
template <typename T>
struct MyFuncImpl<T, 8>
{
    T operator()(const T t) const
    {
        return t >> 32;
    }
};

// Calling this functor will calculate the correct bit-shift at compile time and not emit warnings.
template <typename T>
T MyFunc(const T t)
{
    return MyFuncImpl<T, sizeof(T)>()(t);
}

您还可以为8位和16位类型添加额外的特殊化。 您可以这样使用它:

int main()
{
    uint32_t test1 = 1235434;
    std::cout << MyFunc(test1) << std::endl;

    return 0;
}

我终于解决了这个问题,没有任何模板。 我改用普通重载。 我将代码分解成每个类型的单个函数,并将这些函数从64位宽度级联到8位宽度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM