#include <iostream>

template <int dim, template <int> class T> 
class X {
public:
  X () : x_ ( -1 ) {}  
  // this enum definition causes problems with g++ 3.3.3
  // if enum is not defined, no problems with g++
  // but if we remove line 45, then it's ok for g++ but not ISO
  // standard anymore 
  enum { dimension = dim };
  
  typedef T<dim> TType;

  struct Traits 
  {
    typedef T<dim> TType;
  };
  
	template<int d> 
	int bar () 
  {
    return asImp().template bar<d> ();
  }
  
protected:
  int x_;
  
private:
  // Barton Nackman 
  T<dim> & asImp() 
  {
    return static_cast<T<dim> &> (*this);  
  }
};

template <int dim> 
class A : public X<dim,A> 
{
  typedef A<dim> MyType;
public:
	template<int d> 
	int bar () ;
};


template <int dim> 
template <int d>
inline int A<dim>::bar () 
{
  typename MyType::TType h;
  std::cout << this->x_ << std::endl;
  return d;
}

template <> 
//template <>  
inline int A<0>::bar<0> () 
{
  return -1;
}

template<int dim, template <int> class T>
void foo (X<dim,T> & g)
{
  std::cout << g.template bar<0> () << "\n";
}


int main ()
{
  A<0> a;
  foo(a);
  A<2> b;
  foo(b);
}
