I have a template class X that is intended to call a method of it's template
parameter:
template <class T>
class X {
public:
void doSomething() {
m_t.doSomethingElse();
}
private:
T m_t;
};
Is there any strategy for imposing that the template parameter T should
implement a particular interface? I'd like to be able to do something like:
class Foo {
public:
virtual void doSomethingElse() = 0;
};
template <class T : public Foo>
class X {
... code as above ...
};
And then be able to instantiate a X<Bar> where Bar is derived from Foo.
I'm assuming that either this is possible or there is a better design (which
is probably more likely as templates are starting to do my head in!)
Cheers,
Matt
---------------------------------------------------------------------------
All information contained in this e-mail is confidential and for the use
of the addressee only. If you receive this message in error please notify.
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
Several:
(1) document the requirements on T (and "obviously" in production
code you'd try to choose a more meaningful name than T, and make
sure that it wasn't ALL_CAPS),
(2) note that compilation will fail if T fails to syntactically meet
the requirements which are actually exercised,
(3) concept checking, see for example the boost concept checking
library.
> I'd like to be able to do something like:
>
> class Foo {
> public:
> virtual void doSomethingElse() = 0;
> };
>
> template <class T : public Foo>
> class X {
> ... code as above ...
> };
>
> And then be able to instantiate a X<Bar> where Bar is derived from Foo.
There are templates to determine if a class is derived from another
(at compile time), and static assertion templates, and concept checking
mechanisms.
> I'm assuming that either this is possible or there is a better design (which
> is probably more likely as templates are starting to do my head in!)
There are a number of people including Gabriel dos Reis working on
proposals for adding constrained genericity (the ability to specify
and use constraints on template parameters) to the C++ language
proper. A google search will probably turn something up.
Probably we should discuss this over a beer at some point...
What for? If the parameter type doesn't have such a method, the
code won't compile. Let the user of the template decide how that
method should be implemented.
You could adopt this as a standard way of documenting such things, if
you really need to:
template <class T>
class X
{
void templateConstraint(T &t)
{ Foo &f = t; }
public:
...
};
"Matthew Denner" <ma...@evtechnology.com> wrote in message
news:3CEE0C74...@evtechnology.com...
> Is there any strategy for imposing that the template parameter T should
> implement a particular interface? ...
You could do something like the following, forcing the compiler to emit an
error if the template argument does not have a member of the same name that
matches the excpected fucntion signature.
template <class T>
class X {
public:
X() {
// Force an interface compliance
// check on instantiation.
void (T::*requiredMember)() =
&T::doSomethingElse;
}
...
};
> ... I'd like to be able to do something like:
>
> class Foo {
> public:
> virtual void doSomethingElse() = 0;
> };
>
> template <class T : public Foo>
> class X {
> ... code as above ...
> };
>
> And then be able to instantiate a X<Bar> where Bar is derived from Foo.
Part of the magic of templates is that they allow you to work with types
that implement a certain functionality rather than requiring that things
derive from a certain interface. Forcing the client to derive from your
interface kind of strips away that magic, but, nevertheless, it's possible.
template <class T>
class X {
public:
X() {
// Force a check for a
// Foo-derived type.
T t;
static_cast<Foo&>(t);
}
...
};
I must say that this reply is actually the first time I've tried foricing
such policies on arguments via use of templates, and it's really quite
nifty!