我做了一些实验并收到奇怪的错误消息。在提供的代码中,第9行中有一个错误,它会在模板替换期间带来递归限制,但两个编译器(GCC 4.8.2和CLANG 3.4的日志放在底部)报告
"没有名为T"的类型。
如果有人能解释编译器的奇怪信息,我将不胜感激。
感谢。
typedef unsigned long size_t;
template<class _T, size_t _N>
struct P;
template<class _T>
struct P<_T, 0> {
using T= _T;
};
template<class _T, size_t _N>
struct P {
using T= typename P<_T, 1-_N>::T*; // instead of 1-_N will be _N-1
};
int main(void) {
using namespace my;
using namespace std;
typedef P<int, 0>::T P0; // Ok
typedef P<int, 1>::T P1; // Ok
typedef P<int, 2>::T P2; // Error
typedef P<int, 3>::T P2; // Error
return 0;
}
-------------- Build: (compiler: GNU GCC Compiler)--------------- g++ -std=c++11 -Wall -fexceptions -Weffc++ -pedantic -std=c++11 -g -c : In instantiation of ‘struct P<int, 18446744073709551615ul>’: :10:42: required from ‘struct P<int, 2ul>’ :15:26: required from here :10:42: error: no type named ‘T’ in ‘struct P<int, 2ul>’ using T= typename P<_T, 1-_N>::T*; // instead of 1-_N will be _N-1 ^ : In instantiation of ‘struct P<int, 18446744073709551614ul>’: :10:42: required from ‘struct P<int, 3ul>’ :16:26: required from here :10:42: error: no type named ‘T’ in ‘struct P<int, 3ul>’ Process terminated with status 1 (0 minute(s), 0 second(s)) 2 error(s), 6 warning(s) (0 minute(s), 0 second(s)) -------------- Build: (compiler: LLVM Clang Compiler)--------------- clang++ -std=c++11 -Wall -fexceptions -pedantic -std=c++11 -g -Weffc++ -c :10:40: error: no type named 'T' in 'P<int, 2>' using T= typename P<_T, 1-_N>::T*; // instead of 1-_N will be _N-1 ~~~~~~~~~~~~~~~~~~~~~~^ :10:27: note: in instantiation of template class 'P<int, 18446744073709551615>' requested here using T= typename P<_T, 1-_N>::T*; // instead of 1-_N will be _N-1 ^ :15:17: note: in instantiation of template class 'P<int, 2>' requested here typedef P<int, 2>::T P2; // Error ^ :10:40: error: no type named 'T' in 'P<int, 3>' using T= typename P<_T, 1-_N>::T*; // instead of 1-_N will be _N-1 ~~~~~~~~~~~~~~~~~~~~~~^ :10:27: note: in instantiation of template class 'P<int, 18446744073709551614>' requested here using T= typename P<_T, 1-_N>::T*; // instead of 1-_N will be _N-1 ^ :16:17: note: in instantiation of template class 'P<int, 3>' requested here typedef P<int, 3>::T P2; // Error ^ 2 errors generated. Process terminated with status 1 (0 minute(s), 0 second(s)) 2 error(s), 4 warning(s) (0 minute(s), 0 second(s))
答案 0 :(得分:3)
size_t是无符号整数类型,当用2(P<int, 2>::T
)实例化模板,并在P<_T, 1-_N>::T*
中执行 1-_N 计算时,_std :: numeric_limits :: max() - 1_这是一个非常大的数字,然后再次实例化P<_T, 1-_N>::T*
导致实例化的第一个实例化( with 2 ),在这种情况下是clang和gcc应该检测到这个特定的实例化正在发生,类型T已经不知道(并且永远不会,因为它将生成实例化的无限循环)。
答案 1 :(得分:2)
请注意(1 - (1 - N)) == N
。
正如编译器所述:
struct P<int, 2ul>
取决于struct P<int, 18446744073709551615ul>
,它再次依赖于struct P<int, 2ul>
(其中T
尚未定义(本身有2个指针......)。