Good catch chairthrower.
To elaborate, since the type of Container depends on a template parameter passed to "us", all it's member classes and types are what are known as "dependent typenames" and require the use of the typename keyword:
template <typename T>class A{public: typedef boost::ptr_container< T > Container; typedef typename Container::value_type value_type; typedef typename Container::reference reference; typedef typename Container::const_reference const_reference; typedef typename Container::size_type size_type; typedef typename Container::iterator iterator; typedef typename Container::const_iterator const_iterator;...};
Static functions/variables don't need to be qualified, but member templates also have special syntax:
typedef
typename Container::allocator_type::
template rebind<short>::other::
template rebind<int>::other int_allocator;
Quick explaination: Since the exact type of Container depends on a template parameter of our context, T, a given member... say, Container::foo, could be a static variable for T=char, a static function for T=short, a typedef for T=int, and a template for T=float. The typename keyword is our way of saying that a given expression ends in a type... in this case, that:
Container::...::
other is a type.
Templates are slightly more complicated: We need to use the template keyword at each point they occur, which is why you see it multiple times in my convoluted example, unlike typename:
Container::...::
template rebind is a template. Both times.
HTH