[personal profile] dememax
Я уже публиковал реализацию Решета Эратосфена, в этот раз - реализация более приближенная к классической.
struct Stop;

template<bool B, typename T>
    struct TypeIf
        { typedef T result; };
template<typename T>
    struct TypeIf<false, T>
        { typedef int result; };

template<unsigned N, unsigned I, unsigned E>
struct DivisorIterator
{
    DivisorIterator() {}
    typename TypeIf<I == E, Stop>::result there_are_divisors;
    typename TypeIf<N % I, DivisorIterator<N, I+1, E> >::result next_divisor;
};

template<unsigned N>
struct NumberIterator
{
    DivisorIterator<N, 2, N/2+1> check_cur;
    NumberIterator<N-1> next_number;
};

template<>
struct NumberIterator<3>
{
};

static const NumberIterator<80> a;
А теперь давайте посмотрим на круги, т.е., какие сообщения выводят разные компиляторы. Ведь тема информативности/запутанности вывода компиляции - давольно актуальная тема в контексте ошибок в шаблонах.

Вот, какие компиляторы мне попались под руку (за MS Visual C++ - спасибо Олегу Рябкову!) и сколько они нагенерили вывода компиляции:
Компиляторстроксловсимволовскачать файл
comeau-4.3.10.1546288028484enum_comeau-4.3.10.1.txt
gcc-3.4.61277603474547enum_gcc-3.4.6.txt
gcc-4.5.3300167020538enum_gcc-4.5.3.txt
gcc-4.6.216596611130enum_gcc-4.6.2.txt
msvc-2010637327486269176enum_msvc-2010.txt
Далее приводятся первый и последний сегменты из вывода об ошибках компиляции.

comeau-4.3.10.1

79

"ComeauTest.c", line 14: error: incomplete type is not allowed
      typename TypeIf<I == E, Stop>::result there_are_divisors;
                                            ^
          detected during:
            instantiation of class
                      "DivisorIterator<N, I, E> [with N=79U, I=40U, E=40U]" at
                      line 15
            instantiation of class
                      "DivisorIterator<N, I, E> [with N=79U, I=39U, E=40U]" at
                      line 15
            instantiation of class
                      "DivisorIterator<N, I, E> [with N=79U, I=38U, E=40U]" at
                      line 15
            instantiation of class
                      "DivisorIterator<N, I, E> [with N=79U, I=37U, E=40U]" at
                      line 15
            instantiation of class
                      "DivisorIterator<N, I, E> [with N=79U, I=36U, E=40U]" at
                      line 15
            [ 31 instantiation contexts not shown ]
            instantiation of class
                      "DivisorIterator<N, I, E> [with N=79U, I=4U, E=40U]" at
                      line 15
            instantiation of class
                      "DivisorIterator<N, I, E> [with N=79U, I=3U, E=40U]" at
                      line 15
            instantiation of class
                      "DivisorIterator<N, I, E> [with N=79U, I=2U, E=40U]" at
                      line 21
            instantiation of class "NumberIterator<N> [with N=79U]" at line 22
            instantiation of class "NumberIterator<N> [with N=80U]" at line 30

5

"ComeauTest.c", line 14: error: incomplete type is not allowed
      typename TypeIf<I == E, Stop>::result there_are_divisors;
                                            ^
          detected during:
            instantiation of class
                      "DivisorIterator<N, I, E> [with N=5U, I=3U, E=3U]" at
                      line 15
            instantiation of class
                      "DivisorIterator<N, I, E> [with N=5U, I=2U, E=3U]" at
                      line 21
            instantiation of class "NumberIterator<N> [with N=5U]" at line 22
            instantiation of class "NumberIterator<N> [with N=6U]" at line 22
            instantiation of class "NumberIterator<N> [with N=7U]" at line 22
            [ 68 instantiation contexts not shown ]
            instantiation of class "NumberIterator<N> [with N=76U]" at line 22
            instantiation of class "NumberIterator<N> [with N=77U]" at line 22
            instantiation of class "NumberIterator<N> [with N=78U]" at line 22
            instantiation of class "NumberIterator<N> [with N=79U]" at line 22
            instantiation of class "NumberIterator<N> [with N=80U]" at line 30

gcc-3.4.6

79

enum.cpp: In instantiation of `DivisorIterator<79u, 40u, 40u>':
enum.cpp:15:   instantiated from `DivisorIterator<79u, 39u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 38u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 37u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 36u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 35u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 34u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 33u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 32u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 31u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 30u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 29u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 28u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 27u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 26u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 25u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 24u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 23u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 22u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 21u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 20u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 19u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 18u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 17u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 16u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 15u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 14u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 13u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 12u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 11u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 10u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 9u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 8u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 7u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 6u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 5u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 4u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 3u, 40u>'
enum.cpp:15:   instantiated from `DivisorIterator<79u, 2u, 40u>'
enum.cpp:21:   instantiated from `NumberIterator<79u>'
enum.cpp:22:   instantiated from `NumberIterator<80u>'
enum.cpp:30:   instantiated from here
enum.cpp:14: error: `DivisorIterator<N, I, E>::there_are_divisors' has incomplete type
enum.cpp:1: error: forward declaration of `struct Stop'

5

enum.cpp: In instantiation of `DivisorIterator<5u, 3u, 3u>':
enum.cpp:15:   instantiated from `DivisorIterator<5u, 2u, 3u>'
enum.cpp:21:   instantiated from `NumberIterator<5u>'
enum.cpp:22:   instantiated from `NumberIterator<6u>'
enum.cpp:22:   instantiated from `NumberIterator<7u>'
enum.cpp:22:   instantiated from `NumberIterator<8u>'
enum.cpp:22:   instantiated from `NumberIterator<9u>'
enum.cpp:22:   instantiated from `NumberIterator<10u>'
enum.cpp:22:   instantiated from `NumberIterator<11u>'
enum.cpp:22:   instantiated from `NumberIterator<12u>'
enum.cpp:22:   instantiated from `NumberIterator<13u>'
enum.cpp:22:   instantiated from `NumberIterator<14u>'
enum.cpp:22:   instantiated from `NumberIterator<15u>'
enum.cpp:22:   instantiated from `NumberIterator<16u>'
enum.cpp:22:   instantiated from `NumberIterator<17u>'
enum.cpp:22:   instantiated from `NumberIterator<18u>'
enum.cpp:22:   instantiated from `NumberIterator<19u>'
enum.cpp:22:   instantiated from `NumberIterator<20u>'
enum.cpp:22:   instantiated from `NumberIterator<21u>'
enum.cpp:22:   instantiated from `NumberIterator<22u>'
enum.cpp:22:   instantiated from `NumberIterator<23u>'
enum.cpp:22:   instantiated from `NumberIterator<24u>'
enum.cpp:22:   instantiated from `NumberIterator<25u>'
enum.cpp:22:   instantiated from `NumberIterator<26u>'
enum.cpp:22:   instantiated from `NumberIterator<27u>'
enum.cpp:22:   instantiated from `NumberIterator<28u>'
enum.cpp:22:   instantiated from `NumberIterator<29u>'
enum.cpp:22:   instantiated from `NumberIterator<30u>'
enum.cpp:22:   instantiated from `NumberIterator<31u>'
enum.cpp:22:   instantiated from `NumberIterator<32u>'
enum.cpp:22:   instantiated from `NumberIterator<33u>'
enum.cpp:22:   instantiated from `NumberIterator<34u>'
enum.cpp:22:   instantiated from `NumberIterator<35u>'
enum.cpp:22:   instantiated from `NumberIterator<36u>'
enum.cpp:22:   instantiated from `NumberIterator<37u>'
enum.cpp:22:   instantiated from `NumberIterator<38u>'
enum.cpp:22:   instantiated from `NumberIterator<39u>'
enum.cpp:22:   instantiated from `NumberIterator<40u>'
enum.cpp:22:   instantiated from `NumberIterator<41u>'
enum.cpp:22:   instantiated from `NumberIterator<42u>'
enum.cpp:22:   instantiated from `NumberIterator<43u>'
enum.cpp:22:   instantiated from `NumberIterator<44u>'
enum.cpp:22:   instantiated from `NumberIterator<45u>'
enum.cpp:22:   instantiated from `NumberIterator<46u>'
enum.cpp:22:   instantiated from `NumberIterator<47u>'
enum.cpp:22:   instantiated from `NumberIterator<48u>'
enum.cpp:22:   instantiated from `NumberIterator<49u>'
enum.cpp:22:   instantiated from `NumberIterator<50u>'
enum.cpp:22:   instantiated from `NumberIterator<51u>'
enum.cpp:22:   instantiated from `NumberIterator<52u>'
enum.cpp:22:   instantiated from `NumberIterator<53u>'
enum.cpp:22:   instantiated from `NumberIterator<54u>'
enum.cpp:22:   instantiated from `NumberIterator<55u>'
enum.cpp:22:   instantiated from `NumberIterator<56u>'
enum.cpp:22:   instantiated from `NumberIterator<57u>'
enum.cpp:22:   instantiated from `NumberIterator<58u>'
enum.cpp:22:   instantiated from `NumberIterator<59u>'
enum.cpp:22:   instantiated from `NumberIterator<60u>'
enum.cpp:22:   instantiated from `NumberIterator<61u>'
enum.cpp:22:   instantiated from `NumberIterator<62u>'
enum.cpp:22:   instantiated from `NumberIterator<63u>'
enum.cpp:22:   instantiated from `NumberIterator<64u>'
enum.cpp:22:   instantiated from `NumberIterator<65u>'
enum.cpp:22:   instantiated from `NumberIterator<66u>'
enum.cpp:22:   instantiated from `NumberIterator<67u>'
enum.cpp:22:   instantiated from `NumberIterator<68u>'
enum.cpp:22:   instantiated from `NumberIterator<69u>'
enum.cpp:22:   instantiated from `NumberIterator<70u>'
enum.cpp:22:   instantiated from `NumberIterator<71u>'
enum.cpp:22:   instantiated from `NumberIterator<72u>'
enum.cpp:22:   instantiated from `NumberIterator<73u>'
enum.cpp:22:   instantiated from `NumberIterator<74u>'
enum.cpp:22:   instantiated from `NumberIterator<75u>'
enum.cpp:22:   instantiated from `NumberIterator<76u>'
enum.cpp:22:   instantiated from `NumberIterator<77u>'
enum.cpp:22:   instantiated from `NumberIterator<78u>'
enum.cpp:22:   instantiated from `NumberIterator<79u>'
enum.cpp:22:   instantiated from `NumberIterator<80u>'
enum.cpp:30:   instantiated from here
enum.cpp:14: error: `DivisorIterator<N, I, E>::there_are_divisors' has incomplete type
enum.cpp:1: error: forward declaration of `struct Stop'

gcc-4.5.3

79

enum.cpp: In instantiation of ‘DivisorIterator<79u, 40u, 40u>’:
enum.cpp:15:65:   instantiated from ‘DivisorIterator<79u, 39u, 40u>’
enum.cpp:15:65:   instantiated from ‘DivisorIterator<79u, 38u, 40u>’
enum.cpp:15:65:   instantiated from ‘DivisorIterator<79u, 37u, 40u>’
enum.cpp:15:65:   instantiated from ‘DivisorIterator<79u, 36u, 40u>’
enum.cpp:15:65:   instantiated from ‘DivisorIterator<79u, 35u, 40u>’
enum.cpp:15:65:   [ skipping 30 instantiation contexts ]
enum.cpp:15:65:   instantiated from ‘DivisorIterator<79u, 4u, 40u>’
enum.cpp:15:65:   instantiated from ‘DivisorIterator<79u, 3u, 40u>’
enum.cpp:15:65:   instantiated from ‘DivisorIterator<79u, 2u, 40u>’
enum.cpp:21:34:   instantiated from ‘NumberIterator<79u>’
enum.cpp:22:25:   instantiated from ‘NumberIterator<80u>’
enum.cpp:30:33:   instantiated from here
enum.cpp:14:43: ошибка: ‘DivisorIterator<N, I, E>::there_are_divisors’ has incomplete type
enum.cpp:1:8: ошибка: forward declaration of ‘struct TypeIf<true, Stop>::result’

5

enum.cpp: In instantiation of ‘DivisorIterator<5u, 3u, 3u>’:
enum.cpp:15:65:   instantiated from ‘DivisorIterator<5u, 2u, 3u>’
enum.cpp:21:34:   instantiated from ‘NumberIterator<5u>’
enum.cpp:22:25:   instantiated from ‘NumberIterator<6u>’
enum.cpp:22:25:   instantiated from ‘NumberIterator<7u>’
enum.cpp:22:25:   instantiated from ‘NumberIterator<8u>’
enum.cpp:22:25:   [ skipping 67 instantiation contexts ]
enum.cpp:22:25:   instantiated from ‘NumberIterator<76u>’
enum.cpp:22:25:   instantiated from ‘NumberIterator<77u>’
enum.cpp:22:25:   instantiated from ‘NumberIterator<78u>’
enum.cpp:22:25:   instantiated from ‘NumberIterator<79u>’
enum.cpp:22:25:   instantiated from ‘NumberIterator<80u>’
enum.cpp:30:33:   instantiated from here
enum.cpp:14:43: ошибка: ‘DivisorIterator<N, I, E>::there_are_divisors’ has incomplete type
enum.cpp:1:8: ошибка: forward declaration of ‘struct TypeIf<true, Stop>::result’

gcc-4.6.2

79

enum.cpp: In instantiation of «DivisorIterator<79u, 40u, 40u>»:
enum.cpp:22:69:   recursively instantiated from «DivisorIterator<79u, 3u, 40u>»
enum.cpp:22:69:   instantiated from «DivisorIterator<79u, 2u, 40u>»
enum.cpp:28:34:   instantiated from «NumberIterator<79u>»
enum.cpp:29:25:   instantiated from «NumberIterator<80u>»
enum.cpp:37:33:   instantiated from here
enum.cpp:21:19: ошибка: «DivisorIterator<N, I, E>::stop» has incomplete type
enum.cpp:1:25: ошибка: declaration of «struct False<true>»

5

enum.cpp: In instantiation of «DivisorIterator<3u, 2u, 2u>»:
enum.cpp:29:25:   recursively instantiated from «NumberIterator<79u>»
enum.cpp:29:25:   instantiated from «NumberIterator<80u>»
enum.cpp:37:33:   instantiated from here
enum.cpp:21:19: ошибка: «DivisorIterator<N, I, E>::stop» has incomplete type
enum.cpp:1:25: ошибка: declaration of «struct False<true>»

msvc-2010

79

Привожу не полностью, т.к. уж очень много строк...
c:\temp\cpptest\enum.cpp(15): warning C4305: 'specialization' : truncation from 'const unsigned int' to 'bool'
          c:\temp\cpptest\enum.cpp(15) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=79,
              I=4,
              E=40
          ]
          c:\temp\cpptest\enum.cpp(15) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=79,
              I=3,
              E=40
          ]
          c:\temp\cpptest\enum.cpp(21) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=79,
              I=2,
              E=40
          ]
          c:\temp\cpptest\enum.cpp(22) : see reference to class template instantiation 'NumberIterator<N>' being compiled
          with
          [
              N=79
          ]
          c:\temp\cpptest\enum.cpp(30) : see reference to class template instantiation 'NumberIterator<N>' being compiled
          with
          [
              N=80
          ]
c:\temp\cpptest\enum.cpp(15): warning C4305: 'specialization' : truncation from 'const unsigned int' to 'bool'
          c:\temp\cpptest\enum.cpp(15) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=79,
              I=5,
              E=40
          ]
c:\temp\cpptest\enum.cpp(15): warning C4305: 'specialization' : truncation from 'const unsigned int' to 'bool'
          c:\temp\cpptest\enum.cpp(15) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=79,
              I=7,
              E=40
          ]
          c:\temp\cpptest\enum.cpp(15) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=79,
              I=6,
              E=40
          ]
c:\temp\cpptest\enum.cpp(15): warning C4305: 'specialization' : truncation from 'const unsigned int' to 'bool'
          c:\temp\cpptest\enum.cpp(15) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=79,
              I=8,
              E=40
          ]
c:\temp\cpptest\enum.cpp(15): warning C4305: 'specialization' : truncation from 'const unsigned int' to 'bool'
          c:\temp\cpptest\enum.cpp(15) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=79,
              I=9,
              E=40
          ]
.....................................
c:\temp\cpptest\enum.cpp(15): warning C4305: 'specialization' : truncation from 'const unsigned int' to 'bool'
          c:\temp\cpptest\enum.cpp(15) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=79,
              I=76,
              E=40
          ]
c:\temp\cpptest\enum.cpp(15): warning C4305: 'specialization' : truncation from 'const unsigned int' to 'bool'
          c:\temp\cpptest\enum.cpp(15) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=79,
              I=77,
              E=40
          ]

5

c:\temp\cpptest\enum.cpp(14): error C2079: 'DivisorIterator<N,I,E>::there_are_divisors' uses undefined struct 'Stop'
          with
          [
              N=5,
              I=3,
              E=3
          ]
          c:\temp\cpptest\enum.cpp(15) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=5,
              I=3,
              E=3
          ]
          c:\temp\cpptest\enum.cpp(21) : see reference to class template instantiation 'DivisorIterator<N,I,E>' being compiled
          with
          [
              N=5,
              I=2,
              E=3
          ]
          c:\temp\cpptest\enum.cpp(22) : see reference to class template instantiation 'NumberIterator<N>' being compiled
          with
          [
              N=5
          ]
          c:\temp\cpptest\enum.cpp(22) : see reference to class template instantiation 'NumberIterator<N>' being compiled
          with
          [
              N=6
          ]
c:\temp\cpptest\enum.cpp(15): warning C4305: 'specialization' : truncation from 'const unsigned int' to 'bool'

Вывод

Да, похоже владельцам gcc-3.4.6, а уж тем более msvc-2010 - не позавидуешь при разборе полётов...
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

dememax

May 2023

S M T W T F S
 123456
78910111213
14151617181920
21 2223 24252627
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 10th, 2025 05:13 am
Powered by Dreamwidth Studios