#include <iostream>

template<int N>
struct NumWriter1 {
    static void write() {
        std::cout << "Передано число " << N << std::endl;
    }
};

template<>
struct NumWriter1<0> {
    static void write() {
        std::cout << "Передан нолик" << std::endl;
    }
};

template<int N1, int N2>
struct NumWriter2 {
    static void write() {
        std::cout << "Переданы числа " << N1  << " и " << N2 << std::endl;
    }
};

template<int N2>
struct NumWriter2<0, N2> {
    static void write() {
        std::cout << "Передан нолик и число " << N2 << std::endl;
    }
};

template<int N1>
struct NumWriter2<N1, 0> {
    static void write() {
        std::cout << "Передано число " << N1 << " и нолик" << std::endl;
    }
};

// Если удалить специализацию ниже, то будет ошибка компиляции, потому что
// NumWriter2<0, 0>::write(); подходит как для специализации <0, N2>, так и 
// для <N1, 0> и неясно какую выбирать.
template<>
struct NumWriter2<0, 0> {
    static void write() {
        std::cout << "Переданы два нолика" << std::endl;
    }
};



int main() {
    NumWriter1<10>::write();
    NumWriter1<0>::write();

    NumWriter2<0, 1>::write();
    NumWriter2<0, 234>::write();
    NumWriter2<2, 56>::write();
    NumWriter2<2, 0>::write();
    NumWriter2<0, 0>::write();
    return 0;
}
