C++ 11 递归类模板到复杂错误
c++ 11 recursive class template to complex error
为什么在将 #if 0 更改为 #if 1 时出现"错误 C1202:递归类型或函数依赖上下文太复杂"错误? 错误版本更简单,我宁愿使用类似的东西。
我正在尝试编写一个哈希函数,以消除编译时常量长度的循环。 真正的哈希函数更复杂,这只是一个简单的例子。
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;
}
问题是这个函数在编译时是无限递归的:
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<-7>
......直到达到编译器模板递归限制或编译器内存不足
另一方面,如果您明确地专门化所有情况:
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>
只是一个明确的专业化,该过程就此停止。
这就是为什么当涉及到模板元编程时,你应该将专业化视为你的分支和你的基本递归案例。不要考虑实际的跑步时间早午餐。
相关文章:
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- C++ 复杂库编译错误
- 在重载复杂类的运算符>>时发生分段错误
- 将复杂的参数放入最低功能时会出现错误吗?为什么?(Eclipse C )
- C++ 11 递归类模板到复杂错误
- Visual C++ 2013 和错误 C2065:"复杂":未声明的标识符和错误 C2059:语法错误:","
- 错误 - 复杂::总和的多个声明
- 错误:iostream.h由于包含复杂