Name for a common idiom

G

Gareth Stockwell

I've been using an technique whereby a tag used as a parameter to a
template class C determines which of several potential base classes
(A,B) C inherits from. What I want to know is whether there is an
accepted name for this idiom.

To illustrate the point, here is some code which demonstrates it in
action...

// Selector classes - these are typically just empty structs
struct A_Tag { };
struct B_Tag { };

// Potential base classes
class A { /* ... */ };
class B { /* ... */ };

// Definition of the class which selects the appropriate base for C
template<class Tag> struct Selector { };

// Specialisations of the selector map tags onto base classes
template<> struct Selector<A_Tag> { typedef A base_t; };
template<> struct Selector<B_Tag> { typedef B base_t; };

// OK, here is the class which we actually instantiate
template<class Tag>
class C : public Selector<Tag>::base_t
{ /* ... */ };

// And now the instantiations...
C<A_Tag> c_inheriting_from_A;
C<B_Tag> c_inheriting_from_B;


Gareth
 
G

Gianni Mariani

Gareth said:
I've been using an technique whereby a tag used as a parameter to a
template class C determines which of several potential base classes
(A,B) C inherits from. What I want to know is whether there is an
accepted name for this idiom.

I don't think so, but then I would probably not know if there was one.

....
// OK, here is the class which we actually instantiate
template<class Tag>
class C : public Selector<Tag>::base_t

This is a syntax error. Should be:

class C : public typename Selector<Tag>::base_t
 
P

Peter Koch Larsen

Gareth Stockwell said:
I've been using an technique whereby a tag used as a parameter to a
template class C determines which of several potential base classes
(A,B) C inherits from. What I want to know is whether there is an
accepted name for this idiom.

To illustrate the point, here is some code which demonstrates it in
action...

// Selector classes - these are typically just empty structs
struct A_Tag { };
struct B_Tag { };

// Potential base classes
class A { /* ... */ };
class B { /* ... */ };

// Definition of the class which selects the appropriate base for C
template<class Tag> struct Selector { };

// Specialisations of the selector map tags onto base classes
template<> struct Selector<A_Tag> { typedef A base_t; };
template<> struct Selector<B_Tag> { typedef B base_t; };

// OK, here is the class which we actually instantiate
template<class Tag>
class C : public Selector<Tag>::base_t
{ /* ... */ };

// And now the instantiations...
C<A_Tag> c_inheriting_from_A;
C<B_Tag> c_inheriting_from_B;


Gareth

Why not simply:

template<class base>
class C : public base
{
....
}

?

/Peter
 
M

Michael Kurz

Peter Koch Larsen said:
Why not simply:

template<class base>
class C : public base
{
...
}

I thought exactly this one indirection level is the idiom. :)

And if this is really the case, and the *tag classes do never carry
implementation,
we could discuss if the "switching" template variable should be really a
class or if a numeric type (together with some enum) would be a cleaner, but
perhapes not so flexible solution.


Regards
Michael
 
R

Rob Williscroft

Gianni Mariani wrote in in
comp.lang.c++:
I don't think so, but then I would probably not know if there was one.

...

This is a syntax error. Should be:

class C : public typename Selector<Tag>::base_t

I think this is the one place where typename is specificaly *not*
alowed, I've no idea why it is required after typedef though :).

mscv 7.1
error C2899: typename cannot be used outside a template declaration

g++ 3.2 and 3.3
test.cpp:12: no bases given following `:'
test.cpp:12: parse error before `typename'

bccx (EDG):
test.cpp:12: error expected an identifier

g++ 3.4 & 4.0 (prerelease)
test.cpp:12: error: keyword `typename' not allowed outside of templates

Rob.
 
G

Gareth Stockwell

This is a syntax error. Should be:

class C : public typename Selector<Tag>::base_t

I think the typename keyword is only required inside the body of the
class, not in its definition. I don't have the standard handy, so
I'll be pragmatic ... the above compiles fine with GCC (all versions
3.3.2 up to 3.4.2), and Intel C++ 8.0 :)

Gareth
 
G

Gianni Mariani

Gareth said:
I think the typename keyword is only required inside the body of the
class, not in its definition. I don't have the standard handy, so
I'll be pragmatic ... the above compiles fine with GCC (all versions
3.3.2 up to 3.4.2), and Intel C++ 8.0 :)

That makes sense. My bad.

G
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top