Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can one access the template parameter outside of a template without a typedef?

A simple example:

template<typename _X> // this template parameter should be usable outside!
struct Small {
   typedef _X X; // this is tedious!
   X foo;
};

template<typename SomeSmall>
struct Big {
   typedef typename SomeSmall::X X; // want to use X here!
   SomeSmall bar;
   X toe;
};

Is there a way to access the template parameter X of Small without using a typedef in the Small class?

like image 352
Danvil Avatar asked Sep 12 '10 19:09

Danvil


People also ask

Which parameter is allowed for non-type template?

Which parameter is legal for non-type template? Explanation: The following are legal for non-type template parameters:integral or enumeration type, Pointer to object or pointer to function, Reference to object or reference to function, Pointer to member.

Can a template parameter be a function?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Can a template be a template parameter?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

Can we use non-type parameters as argument templates?

A non-type template argument provided within a template argument list is an expression whose value can be determined at compile time. Such arguments must be constant expressions, addresses of functions or objects with external linkage, or addresses of static class members.


1 Answers

Yes, define a second "getter" template with partial specialization.

template< typename >
struct get_Small_X; // base template is incomplete, invalid

template< typename X > // only specializations exist
struct get_Small_X< Small< X > > {
    typedef X type;
};

Now instead of Small<X>::X you have typename get_Small_X< Small<X> >::type.

By the way, _X is a reserved identifier, so you shouldn't use it for anything. X_ is a better choice.


Advanced topic: template introspection.

While I'm thinking about it, you don't need to define this separately for every template. A single master template should do it.

This compiles in Comeau, I know there are rules about matching template template arguments but I think it's OK… template template arguments are forbidden from the master template in partial specialization.

template< typename >
struct get_first_type_argument;

template< template< typename > class T, typename X >
struct get_first_type_argument< T< X > > {
    typedef X type;
};

template< typename X >
struct simple;

get_first_type_argument< simple< int > >::type q = 5;

This only works with "unary" templates but could be adapted in C++0x for the general case.

like image 179
Potatoswatter Avatar answered Oct 22 '22 23:10

Potatoswatter