首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将c++ 11递归类模板转换为复杂错误

将c++ 11递归类模板转换为复杂错误
EN

Stack Overflow用户
提问于 2015-01-14 03:37:46
回答 1查看 95关注 0票数 0

为什么当将#if 0更改为#if 1时,我会得到一个"error C1202:递归类型或函数依赖上下文太复杂“的错误?错误版本更简单,我宁愿使用类似的东西。

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

代码语言:javascript
复制
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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-14 03:53:51

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

代码语言:javascript
复制
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);
}

当然,您有if语句,所以如果调用Hash<3>,就不会真正期望它要实例化Hash<-1>.但是在模板中,函数的整个主体必须实例化。这些树枝以后才会修剪。因此,无论CB的值如何,Hash的任何实例化都会继续实例化越来越多的CB值(例如,Hash<9>需要Hash<5>Hash<1>需要Hash<-3>Hash<-3>需要Hash<-7> .)直到达到编译器模板递归限制,或者编译器内存不足为止。

另一方面,如果您明确地将所有案例专门化:

代码语言:javascript
复制
template<U4 CB> U4 Hash(const char* sz, int n = 0) {
    return Hash<CB - 4>(sz + 4, n ^ AS4(sz));
}

template <> U4 Hash<3>(const char* sz, int n = 0) {
    return n ^ AS3(sz);
}

// etc.

然后,比方说,Hash<9>的实例化将导致Hash<5>的实例化,然后Hash<1>只是一个显式的专门化,流程就停止了。

这就是为什么当涉及到模板元编程时,您应该将专门化看作是您的分支和基本递归案例。不要考虑实际的运行时间延迟。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27935471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档