#include <type_traits>
#include <iostream>

template<class C, class T = int>
using EnableIf = typename std::enable_if<C::value, T>::type;

template<int N, int M>
struct is_multiple_of : std::integral_constant<bool, N % M == 0>{};

template<unsigned I> struct choice : choice<I+1>{};
template<> struct choice<10>{};

struct otherwise{ otherwise(...){} };

struct select_overload : choice<0>{};

template<unsigned N, EnableIf<is_multiple_of<N, 15>>...>
void print_fizzbuzz(choice<0>){ std::cout << "fizzbuzz\n"; }

template<unsigned N, EnableIf<is_multiple_of<N, 21>>...>
void print_fizzbuzz(choice<1>){ std::cout << "fizzbeep\n"; }

template<unsigned N, EnableIf<is_multiple_of<N, 33>>...>
void print_fizzbuzz(choice<2>){ std::cout << "fizznarf\n"; }

template<unsigned N, EnableIf<is_multiple_of<N, 35>>...>
void print_fizzbuzz(choice<3>){ std::cout << "buzzbeep\n"; }

template<unsigned N, EnableIf<is_multiple_of<N, 55>>...>
void print_fizzbuzz(choice<4>){ std::cout << "buzznarf\n"; }

template<unsigned N, EnableIf<is_multiple_of<N, 77>>...>
void print_fizzbuzz(choice<5>){ std::cout << "beepnarf\n"; }

template<unsigned N, EnableIf<is_multiple_of<N, 3>>...>
void print_fizzbuzz(choice<6>){ std::cout << "fizz\n"; }

template<unsigned N, EnableIf<is_multiple_of<N, 5>>...>
void print_fizzbuzz(choice<7>){ std::cout << "buzz\n"; }

template<unsigned N, EnableIf<is_multiple_of<N, 7>>...>
void print_fizzbuzz(choice<8>){ std::cout << "beep\n"; }

template<unsigned N, EnableIf<is_multiple_of<N, 11>>...>
void print_fizzbuzz(choice<9>){ std::cout << "narf\n"; }

// we stay with the ellipsis for the general case, so we
// don't have to adjust anything if new overloads are added
template<unsigned N>
void print_fizzbuzz(otherwise){ std::cout << N << "\n"; }

template<unsigned N = 1>
void do_fizzbuzz(){
    print_fizzbuzz<N>(select_overload{});
    do_fizzbuzz<N+1>();
}

template<>
void do_fizzbuzz<100>(){
    print_fizzbuzz<100>(select_overload{});
}

int main(){
  do_fizzbuzz();
}