Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;11递归类模板到复杂错误_C++_Templates_C++11_Recursion - Fatal编程技术网

C++ c++;11递归类模板到复杂错误

C++ c++;11递归类模板到复杂错误,c++,templates,c++11,recursion,C++,Templates,C++11,Recursion,为什么在将#if 0更改为#if 1时会出现“error C1202:recursive type or function dependency context too complex”错误?错误版本更简单,我宁愿使用类似的东西 我试图编写一个哈希函数,消除编译时常量长度的循环。真正的哈希函数更复杂,这只是一个简单的例子 typedef unsigned __int8 U1; typedef unsigned __int16 U2; typedef unsigned __int32 U4; #d

为什么在将#if 0更改为#if 1时会出现“error C1202:recursive type or function dependency context too complex”错误?错误版本更简单,我宁愿使用类似的东西

我试图编写一个哈希函数,消除编译时常量长度的循环。真正的哈希函数更复杂,这只是一个简单的例子

typedef unsigned __int8 U1;
typedef unsigned __int16 U2;
typedef unsigned __int32 U4;
#define  AS1(a_)        (*(U1*)(a_))
#define  AS2(a_)        (*(U2*)(a_))
#define  AS3(a_)        ((U4(((U1*)(a_))[2])<<16) | AS2(a_))
#define  AS4(a_)        (*(U4*)(a_))

#if 0
template<U4 CB> U4 Hash(const char* sz, int n = 0) {
    if (CB >= 4) return Hash<CB - 4>(sz + 4, n ^ AS4(sz));
    if (CB == 3) return n ^ AS3(sz);
    if (CB == 2) return n ^ AS2(sz);
    if (CB == 1) return n ^ AS1(sz);
}
#else
template<U4 CB> U4 Hash(const char* sz) {
    return Hash<CB - 4>(sz + 4, Hash<4>(sz));
}
template<U4 CB> U4 Hash(const char* sz, int n) {
    return Hash<CB - 4>(sz + 4, Hash<4>(sz, n));
}
template<> U4 Hash<1>(const char* sz, int n)        { return n ^ AS1(sz); }
template<> U4 Hash<2>(const char* sz, int n)        { return n ^ AS2(sz); }
template<> U4 Hash<3>(const char* sz, int n)        { return n ^ AS3(sz); }
template<> U4 Hash<4>(const char* sz, int n)        { return n ^ AS4(sz); }
template<> U4 Hash<1>(const char* sz)           { return AS1(sz); }
template<> U4 Hash<2>(const char* sz)           { return AS2(sz); }
template<> U4 Hash<3>(const char* sz)           { return AS3(sz); }
template<> U4 Hash<4>(const char* sz)           { return AS4(sz); }
#endif

int main(int argc, char* argv[])
{
    char* sz = "123456789";
    int n = Hash<9>(sz);
    n += Hash<3>(sz);
    return n;
}
typedef unsigned\uu int8 U1;
typedef unsigned_uuint16 U2;
typedef无符号uu int32 U4;
#定义AS1(a_U1)(*(U1*)(a_1))
#定义AS2(a_U2)(*(U2*)(a_2))

#定义AS3(a_417;((U4)((U1*)(a_417;))[2])问题是这个函数在编译时是无限递归的:

template<U4 CB> U4 Hash(const char* sz, int n = 0) {
    if (CB >= 4) return Hash<CB - 4>(sz + 4, n ^ AS4(sz));
    if (CB == 3) return n ^ AS3(sz);
    if (CB == 2) return n ^ AS2(sz);
    if (CB == 1) return n ^ AS1(sz);
}
然后,比如说,
散列
的实例化将导致
散列
的实例化,然后
散列
只是一个显式的专门化,过程就此停止


这就是为什么当涉及到模板元编程时,您应该将专门化视为您的分支和基本递归情况。不要考虑实际的运行时早午餐。

问题是此函数在编译时是无限递归的:

template<U4 CB> U4 Hash(const char* sz, int n = 0) {
    if (CB >= 4) return Hash<CB - 4>(sz + 4, n ^ AS4(sz));
    if (CB == 3) return n ^ AS3(sz);
    if (CB == 2) return n ^ AS2(sz);
    if (CB == 1) return n ^ AS1(sz);
}
然后,比如说,
散列
的实例化将导致
散列
的实例化,然后
散列
只是一个显式的专门化,过程就此停止


这就是为什么当涉及到模板元编程时,您应该将专门化视为您的分支和基本递归情况。不要考虑实际的运行时早午餐。

问题是此函数在编译时是无限递归的:

template<U4 CB> U4 Hash(const char* sz, int n = 0) {
    if (CB >= 4) return Hash<CB - 4>(sz + 4, n ^ AS4(sz));
    if (CB == 3) return n ^ AS3(sz);
    if (CB == 2) return n ^ AS2(sz);
    if (CB == 1) return n ^ AS1(sz);
}
然后,比如说,
散列
的实例化将导致
散列
的实例化,然后
散列
只是一个显式的专门化,过程就此停止


这就是为什么当涉及到模板元编程时,您应该将专门化视为您的分支和基本递归情况。不要考虑实际的运行时早午餐。

问题是此函数在编译时是无限递归的:

template<U4 CB> U4 Hash(const char* sz, int n = 0) {
    if (CB >= 4) return Hash<CB - 4>(sz + 4, n ^ AS4(sz));
    if (CB == 3) return n ^ AS3(sz);
    if (CB == 2) return n ^ AS2(sz);
    if (CB == 1) return n ^ AS1(sz);
}
然后,比如说,
散列
的实例化将导致
散列
的实例化,然后
散列
只是一个显式的专门化,过程就此停止


这就是为什么当涉及到模板元编程时,你应该将专门化看作是你的分支和基本递归情况。不要考虑实际的运行时早午餐。

有什么方法可以简化它,这样我就不需要一个取n的和一个不取n的了吗?@johnnycrash你可以重写成这样
散列(sz)
只是
返回AS4(sz)^Hash(sz+4);
但是最好保持它的尾部递归,你必须检查编译器对它做了什么。有没有办法简化它,这样我就不需要一个取n的和一个不取n的?@johnnycras你可以重写成
Hash(sz)
就是
返回AS4(sz)^Hash(sz+4);
但是最好保持它的尾部递归,你必须检查编译器对它做了什么。有没有办法简化它,这样我就不需要一个取n,一个不取n?@johnnycrash你可以重写成
Hash(sz)
就是
返回AS4(sz)^Hash(sz+4);
但最好保持尾部递归,你必须检查你的编译器对它做了什么。有没有办法简化它,这样我就不需要一个取n的和一个不取n的?@johnnycrash你可以重写成
Hash(sz)
就是
返回AS4(sz)^Hash(sz+4);
但是最好保持它的尾部递归,您必须检查编译器对它做了什么。