我正在尝试使用元编程技术创建一个编译时位掩码,我的想法是创建如下内容:

unsigned int Mask3 = Mask<2>(); // value = 0x03 = b00000000000000000000000000000011
unsigned int Mask3 = Mask<3>(); // value = 0x07 = b00000000000000000000000000000111
unsigned int Mask3 = Mask<7>(); // value = 0x7F = b00000000000000000000000001111111

我正在尝试的代码是这样的:
template <const unsigned int N> const unsigned int Mask()
{
    if (N <= 1)
    {
        return 1;
    }
    else
    {
        return ((1 << N) | Mask<N - 1>());
    }
}

返回1;

但这会导致成对的警告:
  • 警告C4554:'<
  • 警告C4293:'<
    最后,编译错误:
  • 错误C1202:递归类型或函数依赖项上下文太复杂。

  • 因此,我推断出递归性永远不会结束,并且会陷入编译器无限循环中,但是我不理解为什么。

    最佳答案

    正如已经指出的那样,您依赖于运行时检查来
    停止无法执行的编译时间递归。更重要的是,
    也许,对于您想做的是定义一个函数,
    除非您调用它,否则它没有任何值(value)。因此,即使您停止了
    特化的递归,您仍然有一个嵌套序列
    函数,将在运行时调用。

    如果要全面评估编译时间,则必须定义静态数据
    类模板的成员,因为这是编译时的唯一方法
    常量可以出现在模板中。就像是:

    template <unsigned int N>
    struct Mask
    {
        static unsigned int const value = (1 << (N - 1)) | Mask<N - 1>::value;
    };
    
    template <>
    struct Mask<0>
    {
        static unsigned int const value = 0;
    };
    

    (我还纠正了您输入错误的数值。)

    当然,您不需要任何复杂的东西。以下
    应该做到这一点:
    template <unsigned int N>
    struct Mask
    {
        static unsigned int const value = (1 << (N + 1)) - 1;
    };
    
    template <>
    struct Mask<0>
    {
        static unsigned int const value = 0;
    };
    

    (您仍然需要将特殊化设置为0。否则,0表示所有位
    组。)

    最后,当然:要获取值,您需要编写一些内容
    Mask<3>::value一样。 (您可能希望将其包装在宏中。)

    关于c++ - 用于编译时位掩码的递归模板,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11778763/

    10-11 17:04