[Insight-developers] typename platform conflict

Brad King brad.king@kitware.com
Tue, 13 Mar 2001 18:10:26 -0500 (EST)


Jim,

> Can we solve this by inserting a dummy class, so the code would look like
> 
> template<type T>
> class DummyTrait
> {
>     typedef T::SomeType SomeType;
> }
> 
> typename<class T1, class T2 = DummyTrait<T1>::SomeType>
> class X{}
> 
> instead of using a macro. (Can you tell I hate macros....)
Sorry, but no.  This goes back to the reason the typename keyword exists
in the first place:

template <typename T>
struct DummyTrait
{
  typedef T::SomeType SomeType;
};

template <class T1, class T2 = DummyTrait<T1>::SomeType>
class X {};

// .....

template <>
struct DummyTrait<int>
{
  enum { SomeType = 1 };
};

// .....

template class X<int>; // uh-oh!

Obviously we wouldn't ever write the specialization of DummyTrait, but the
compiler doesn't know if we might do this or not when it parses
DummyTrait<T1>::SomeType.  The typename keyword exists to enforce that
SomeType will be a type.

I'm quite confident that the macro is the only solution, but at least it
is a somewhat clean macro.  If you want to see nasty macro usage, look at
BOOST classes.  They have code that looks something like:

template <class T1, class T2 BOOST_DEFAULT_TEMPLATE_ARGUMENT(T1::SomeType) >
class X {};

so that they can remove the use of default arguments on compilers that
don't support them as well as adjust the use of the typename keyword.

-Brad