2009-12-09 4 views
3

Я написал код суждения четных/нечетных чисел с шаблонами C++.Как понять результат вывода с шаблонами C++

#include <iostream> 

template <int N, int Mod2=N%2> 
struct Print { 
    Print() { 
    std::cout << N << std::endl; 
    } 
}; 

template <int N> 
struct Print<N, 0> { 
    Print() { 
    std::cout << "Even!" << std::endl; 
    } 
}; 

template <int N> 
struct Print<N, 1> { 
    Print() { 
    std::cout << "Odd!" << std::endl; 
    } 
}; 

template <int N> 
struct EvenOdd { 
    EvenOdd() { 
    EvenOdd<N+1>(); 
    Print<N>(); 
    } 
}; 

template <> 
struct EvenOdd<10> { 
    EvenOdd() { 
    std::cout << "Hey!" << std::endl; 
    } 
}; 

int main() 
{ 
    EvenOdd<0>(); 
    return 0; 
} 

Этот код выводит:

$ ./a.out 
Hey! 
Odd! 
Even! 
Odd! 
Even! 
Odd! 
Even! 
Odd! 
Even! 
Odd! 
Even! 

я предсказал, что

EvenOdd<10>::EvenOdd() //=> "Hey!"
называется, наконец. Но это ошибка.

Почему «Эй!» вывода во-первых?

ответ

6

Ваш шаблон EvenOdd явно специализирован для параметра 10 только конструкторы всех других специализаций экземпляр анонимного EvenOdd для параметра шаблона N+1 в качестве первого действия в их конструктора.

Это означает, что EvenOdd конструктор будет рекурсивно генерирует анонимные EvenOdd временных объектов до параметра шаблона 10 до того, как объект EvenOdd строит объект Print.

Построение объекта 11-го EvenOdd приводит к выводу «Hey!», Затем строится первый объект Print.

8

Это поведение не имеет ничего общего с шаблонами. Это основная рекурсия. Вы рекурсивно создаете EvenOddдо печать. Итак, первый экземпляр для печати - это самый внутренний, который является EvenOdd<10>.

Это то, что происходит: первое, что нужно сделать EvenOdd<0>, это создать экземпляр EvenOdd<1>. Только когда это завершается, он вызывает Print<0>. И это не завершается до тех пор, пока EvenOdd<1> не закончит создание EvenOdd<2> и не распечатал и так далее:

EvenOdd<0> 
EvenOdd<1> 
    EvenOdd<2> 
    EvenOdd<3> 
    EvenOdd<4> 
    EvenOdd<5> 
     EvenOdd<6> 
     EvenOdd<7> 
     EvenOdd<8> 
     EvenOdd<9> 
      EvenOdd<10> 
      std::cout << "Hey!" << std::endl; 
     Print<9> 
     Print<8> 
     Print<7> 
     Print<6> 
    Print<5> 
    Print<4> 
    Print<3> 
    Print<2> 
Print<1> 
Print<0> 
Смежные вопросы