C++ 模板递归中的非类型模板参数收缩

C++ 模板递归中的非类型模板参数收缩,c++,templates,c++11,C++,Templates,C++11,我有下面的代码,它应该在编译时计算字节中的位数 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 <<

我有下面的代码,它应该在编译时计算字节中的位数

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();
}
模板
结构字符位
{
静态constexpr size\u t get()noexcept{

返回c>0?char\u bit我不确定为什么会发生这种情况。但我认为,您可以使用模板函数专门化来修复它

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; }
};
模板
结构字符位
{
静态constexpr size\u t get()noexcept{

return char_bit避免此错误的一种方法是反向执行:不是溢出字符,而是从最大向右移位开始,直到达到零。您需要专业化才能使代码正常工作(无论如何,您都需要它):

#包括
使用名称空间std;
模板
结构字符位
{
静态constexpr size\u t get()noexcept{
返回字符位<(c>>1),I+1>::get();
}
};
模板
结构字符位
{
静态constexpr size\u t get()noexcept{
返回I;
}
};
int main()
{   
constexpr unsigned char c=static_cast(-1);

std::coutOP说这是有效的,所以我将其作为答案发布:

char_bit<(unsigned char)(c << 1), I + 1>::get()

char\u bit已经有了一个标准宏:

#include <climits>

int main() {
    std:cout << CHAR_BIT << std::endl;
}
#包括
int main(){

std:你没试过吗_bit@SvenNilsson为什么这两种方法都有效?@SvenNilsson我不会做第一种,因为它会将一个字节的大小限制在8位。今天这听起来是合法的,但你永远不知道。此外,这违背了OP的目标精神。是的,它们有效,因为它们将最大值限制在255位
#include <climits>

int main() {
    std:cout << CHAR_BIT << std::endl;
}