在C ++模板部分规范中生成1-N奇怪错误,为什么?

时间:2014-07-18 12:56:37

标签: c++ templates c++11 template-specialization

我做了一些实验并收到奇怪的错误消息。在提供的代码中,第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))

2 个答案:

答案 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个指针......)。