【发布时间】:2016-11-12 09:27:33
【问题描述】:
请考虑以下代码。它是一个函数模板,根据其位宽对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。
【问题讨论】:
-
所有代码都必须编译。取决于
typeBitCount的选择只发生在运行时,而不是编译时。因此,当编译器遇到这些行时,您会收到警告。 -
这很清楚。问题是如何尽可能干净地解决这个问题。
-
如果你有一个 C++14 编译器,你也许可以将整个函数变成一个
constexpr函数并让它评估一个编译时间(取决于“这里的更多代码...... “ 部分)。这可能会解决你的一些问题。或者您可以将函数专门用于 8 位类型,并将常见的“这里有更多代码...”部分放在单独的函数中。 -
在 C++14 之前,您需要引入一个模板化的帮助类,其中一个模板参数是一个整数值,等于
sizeof(T)(或sizeof(T)*8),并且(可能是静态的) ) 成员函数来执行所需的操作。然后使用模板部分特化为sizeof(T)的每个有效值实例化该类及其函数。这意味着您不能“不将代码分解成碎片”就可以逃脱,但这是寻求编译时机制的代价 - 模板(部分)专业化是基本的编译时机制,在运行时完成使用if -
@Some程序员老兄:使用C++14我实际上可以制作函数constexpr。但是警告仍然存在。
标签: c++ c++11 templates bit-shift compile-time