我有以下代码,它应该在编译时计算字节中的位数。
template<unsigned char c, size_t I>
struct char_bit
{
static constexpr size_t get() noexcept {
return c > 0 ? char_bit<c << 1, I + 1>::get() : I
}
};
int main()
{
std::cout << char_bit<1, 0>::get();
}
通过将1
传递给unsigned char
参数,我期望得到8的最终结果,因为它将向左移动8次,直到char变为0。
但是,使用Clang 3.7.1进行编译时,出现了编译错误:
错误:非类型模板参数的计算结果为256,但不能 缩小为'unsigned char'[-Wc ++ 11-narrowing]
为什么会这样?我该如何解决?
答案 0 :(得分:3)
避免此错误的一种方法是反过来:不是溢出你的char,而是从最大和右移开始直到你达到零。你需要一个专门化来使代码工作(无论如何你都需要它):
#include <iostream>
using namespace std;
template<unsigned char c, size_t I>
struct char_bit
{
static constexpr size_t get() noexcept {
return char_bit< (c >> 1), I + 1>::get();
}
};
template<size_t I>
struct char_bit<0, I>
{
static constexpr size_t get() noexcept {
return I;
}
};
int main()
{
constexpr unsigned char c = static_cast<unsigned char>(-1);
std::cout << char_bit<c, 0>::get();
}
答案 1 :(得分:2)
已有一个标准宏:
#include <climits>
int main() {
std:cout << CHAR_BIT << std::endl;
}
答案 2 :(得分:1)
char_bit<(unsigned char)(c << 1), I + 1>::get()
答案 3 :(得分:0)
我不确定为什么会这样。但我认为,您可以使用模板功能专业化来修复它。
template<unsigned char c, size_t I>
struct char_bit
{
static constexpr size_t get() noexcept {
return char_bit<(c << 1), I + 1>::get();
}
};
template <size_t I>
struct char_bit<0, I>
{
static constexpr size_t get() noexcept { return I; }
};