#include <iostream>
using namespace std;

//configure function
template <int n> int f()
{
    return n;
}

template <class T, T n> T f2()
{
    return n;
}

//virtual class
template <class Derived>
struct base
{
    void interface()
    {
         // ...
         static_cast<Derived*>(this)->implementation();
         // ...
    }
};
 
struct derived : base<derived>
{
     void implementation()
     {
        cout << "H\n";
     }
};

struct derived2 : base<derived2>
{
     void implementation()
     {
        cout << "h\n";
     }
};

template <class T> // T is deduced at compile-time
void bar(base<T> * obj) {
  obj->interface(); // will do static dispatch
}

//recursive
template < int n >
struct inc{
    static const int val =  inc<n-1>::val *2;
};

template <>
struct inc<0>{
    static const int val = 1;
};

//test

int main()
{
    cout << "dog\n";

    cout << f<5>() << endl;
    
    cout << f2<int,5>() << endl;

    base <derived>*pBase;
    pBase = new derived;
    //pBase->interface(); //outputs "Derived"
    bar(pBase);
    delete pBase;
    
    cout << inc<5>::val << endl;

    return 0;
}
