Sign in to follow this  
bulgurmayo

typedef and template parameter in C++

Recommended Posts

bulgurmayo    114
Hi, is the following piece of code valid Cpp. Or am I exposing myself to the dangers of undefined behaviour :
template <typename T>
class A
{
public:
  typedef boost::ptr_container< T >    Container;
  typedef Container::value_type        value_type;
  typedef Container::reference         reference;
  typedef Container::const_reference   const_reference;
  typedef Container::size_type         size_type;
  typedef Container::iterator          iterator;
  typedef Container::const_iterator    const_iterator;

...

};

The thing I am worried about is this :
  typedef boost::ptr_container< T >    Container;

Share this post


Link to post
Share on other sites
chairthrower    440
there needs to be a typename in there depending on how conformant your compiler is - maybe not vs6

template< class T>  
struct C
{
typedef ptr_vector< T> container;
typedef typename container::value_type value_type;
};


also consider derivation - its not necessarily right but depending on use can give you the typing information

template< class T>  
struct B : public ptr_vector< T>
{

};
B< int>::value_type elt;









Share this post


Link to post
Share on other sites
Bregma    9214
Quote:
Original post by bulgurmayo
is the following piece of code valid Cpp. Or am I exposing myself to the dangers of undefined behaviour

It's not undefined behaviour. It's perfectly defined. Your code is ambiguous and will not compile under a conforming compiler. As mentioned above, you need to qualify the dependant names with a 'typename' decorator to disambiguate during two-phase name lookup.

You see a lot of exactly that sort of construct all through the standard library code. It's not only OK but the C++ gods beheld it and it was good.

--smw

Share this post


Link to post
Share on other sites
MaulingMonkey    1730
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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this