#include <list>


struct functor_base {};

template <class T_action>
struct limit_derived_target
{
  typedef limit_derived_target<T_action> type_self;

  //If with_type is not an inner class, then it is not ambiguous.
  template <class T_type, bool I_derived>
  struct with_type
  {
  };

  template <class T_type> struct
  with_type<T_type, true>
  {
  };

  void some_method() const
  {
    //SUN CC 5.7 says that this is an ambiguous partial specialization:
    typedef with_type<int, true> type_problem;

    //If I do this, to specify with_type as an inner class, SUN CC 5.5 says
    //"expected init-declarator before "type_problem"
    //typedef type_self::with_type<int, true> type_problem;
  }

  limit_derived_target()
  {}

};


template <class T_action, class T_functor>
void visit_each(const T_action& _A_action, const T_functor& _A_functor)
{
 _A_action.some_method(); 
}



template <class T_action>
void visit_each_type(const T_action& _A_action)
{
  typedef limit_derived_target<T_action> type_limited_action;

  type_limited_action limited_action;

  functor_base functor;
  visit_each(limited_action, functor);
}


typedef void (*hook)(void);

class slot_rep
{
public:
  slot_rep(hook somefunc1__, hook somefunc2__)
   {}
};


class someclass1
{
};


class someclass2
{
};


class slot_base : public functor_base
{
public:


  explicit slot_base(slot_rep* rep = 0);

  
};


slot_base::slot_base(slot_rep* rep)
{}


struct typed_slot_rep : public slot_rep
{
  typed_slot_rep(const functor_base& functor)
    : slot_rep(&somefunc1, &somefunc2)
    {  }

  typed_slot_rep(const typed_slot_rep& cl)
    : slot_rep(0, 0)
    {
      visit_each_type(someclass1());
    }


  static void somefunc1()
    {
 
      visit_each_type(someclass2());
    }


  static void somefunc2()
    {
      typed_slot_rep* temp = 0;
      slot_rep* a_rep = new typed_slot_rep(*temp);
    }
};


class slot0
  : public slot_base
{

public:
 

  slot0(const functor_base& _A_func)
    : slot_base(new typed_slot_rep(_A_func))
    {
    }

};



int main()
{
  slot0 sl = functor_base();
}
