请考虑以下代码。它是一个函数模板,根据其位宽取决于<!--Create frame and assign callbacks to event handlers-->
<button type="button" onclick="increaseRadius()">Increase Radius</button>
<button type="button" onclick="decreaseRadius()">Decrease Radius</button>
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #000000;"></canvas>
类型。实际代码更复杂,但这无关紧要:
T
我也使用8位类型。在那种情况下,我会收到警告(参见注释行)。遗憾的是,即使使用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
}
}
}
}
,C ++也无法在编译期间评估if
条件。我可以抑制警告,但这对我来说似乎很骇人听闻。我宁愿在编译时排除有问题的代码。
如何解决这个问题(可能不会破坏代码并且不会造成冗余)?
我正在使用GCC 5.4.0。
答案 0 :(得分:1)
我计算出有问题的转变,以便:
如果不应该执行它,它有一些小值0:
....
constexpr uint8_t shift2 = (typeBitCount >= 64) ? 32 : 0;
....
if (typeBitCount >= 64)
{
if (...)
{
return t >> shift2;
}
}
....
答案 1 :(得分:1)
您可以使用类似于this answer的部分模板特化来使用仿函数实现依赖于类型大小的函数:
// 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;
}
答案 2 :(得分:0)
我终于解决了这个没有任何模板。我用简单的重载代替了。我将代码分解成各个类型的单个函数,将这些函数从64位宽度级联到8位宽度。