Problems specifying a template declaration

N

Neil Steiner

I have an enum foo, and a template class bar that requires a foo as its
parameter:

enum foo {};
template <foo F> class bar {};

I then want to define another template class that takes a foo and a
bar<foo> or subclass as its parameters:

template <foo F, template <foo F> class bar B> class dummy {};

I know that's wrong because gcc tells me so: "Expected '>' before 'B'"

I can drop the B and just require a bar<F> as the second parameter, but
I really want the B argument because the parameter could be a subclass
of bar<F>, and I need to know its type.

The mistake is probably obvious to many of you. If you could enlighten
me, I would much appreciate it.
 
B

Bo Persson

Neil said:
I have an enum foo, and a template class bar that requires a foo as
its parameter:

enum foo {};
template <foo F> class bar {};

I then want to define another template class that takes a foo and a
bar<foo> or subclass as its parameters:

template <foo F, template <foo F> class bar B> class dummy {};

I know that's wrong because gcc tells me so: "Expected '>' before
'B'"
I can drop the B and just require a bar<F> as the second parameter,
but I really want the B argument because the parameter could be a
subclass of bar<F>, and I need to know its type.

The mistake is probably obvious to many of you. If you could
enlighten me, I would much appreciate it.

You can't specify that a template parameter must be a subclass of some
other class. In C++0x you will have concepts and type_traits to handle
that, but right now you can't specify the detailed requirements.

I guess your best choice is to drop the 'bar' and accept any type B
that takes a foo template parameter. If it is really important,
perhaps you can use a dynamic_cast as a runtime check for the correct
type?


Bo Persson
 
N

Neil Steiner

Bo said:
You can't specify that a template parameter must be a subclass of some
other class. In C++0x you will have concepts and type_traits to handle
that, but right now you can't specify the detailed requirements.

Thanks for the response.

To clarify, are you simply saying that I can't require that argument 2
be a subclass of bar<F>, or are you also saying that I can't require
I guess your best choice is to drop the 'bar' and accept any type B
that takes a foo template parameter. If it is really important,
perhaps you can use a dynamic_cast as a runtime check for the correct
type?

Not a bad idea. It sounds as though that may be my only recourse, so
I'll keep that option in the back of my head.
 
V

Vidar Hasfjord

I have an enum foo, and a template class bar that requires a foo as its
parameter:

     enum foo {};
     template <foo F> class bar {};

I then want to define another template class that takes a foo and a
bar<foo> or subclass as its parameters:

     template <foo F, template <foo F> class bar B> class dummy {};

Since you want to bind the parameter of the bar template to F, it
seems to me that you don't actually want a template as the second
parameter but simply a type:

template <foo F, class B_derived_from_bar_F> class dummy {};

As explained in other replies you cannot directly express the
restrictions on our second parameter. You can use meta-programming
though:

enum foo {a, b};
template <foo F> class bar {};

template <foo F, class D>
class dummy {
BOOST_STATIC_ASSERT
((boost::is_base_of <bar <F>, D>::value));
};

// Test:

template <foo F> class derived : public bar <F> {};
dummy <a, derived <a> > ok1;
dummy <a, derived <b> > error1;
dummy <a, int> error2;

Regards,
Vidar Hasfjord
 
N

Neil Steiner

Vidar said:
Since you want to bind the parameter of the bar template to F, it
seems to me that you don't actually want a template as the second
parameter but simply a type:

template <foo F, class B_derived_from_bar_F> class dummy {};

As explained in other replies you cannot directly express the
restrictions on our second parameter. You can use meta-programming
though:

enum foo {a, b};
template <foo F> class bar {};

template <foo F, class D>
class dummy {
BOOST_STATIC_ASSERT
((boost::is_base_of <bar <F>, D>::value));
};

// Test:

template <foo F> class derived : public bar <F> {};
dummy <a, derived <a> > ok1;
dummy <a, derived <b> > error1;
dummy <a, int> error2;

Regards,
Vidar Hasfjord

Not a bad suggestion. Thank you for the response (and for the code sample).
 

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
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top