Templates - Requiring typename to inherit from a particular class?

V

Victor Bazarov

Is it possible to force the typename of a template to inherit from a
particular class? For example, something like this (conceptual; this
doesn't compile):

class Parent {
public:
[...]
virtual void vfn() = 0;
};

template <child-of-Parent T>
class CC {
[...]
void foo() {
vfn();
}
};

In other words, can I force T to be a child of Parent?

What you can do is issue a compile-time assertion using Boost's
'is_base_and_derived'. See the news archives for suggestions.

V
 
B

blah

Hi,

Is it possible to force the typename of a template to inherit from a
particular class? For example, something like this (conceptual; this
doesn't compile):

class Parent {
public:
[...]
virtual void vfn() = 0;
};

template <child-of-Parent T>
class CC {
[...]
void foo() {
vfn();
}
};

In other words, can I force T to be a child of Parent?

Thanks
 
B

blah

Hi,

Is it possible to force the typename of a template to inherit from a
particular class? For example, something like this (conceptual; this
doesn't compile):

class Parent {
public:
[...]
virtual void vfn() = 0;
};

template <child-of-Parent T>
class CC {
[...]
void foo() {
vfn();
}
};

In other words, can I force T to be a child of Parent?

Thanks


My mistake, the line in foo() should be:
T bar;
bar.vfn();

Sorry.
 
P

Peter_Julian

| Hi,
|
| Is it possible to force the typename of a template to inherit from a
| particular class? For example, something like this (conceptual; this
| doesn't compile):
|
| class Parent {
| public:
| [...]
| virtual void vfn() = 0;
| };
|
| template <child-of-Parent T>

you meant:

template< class Child_of_Parent >

or

template< typename Child_of_Parent >

| class CC {
| [...]
| void foo() {
| vfn();
| }
| };
|
| In other words, can I force T to be a child of Parent?
|

You already have set that requirement. The call to vfn() above is only
valid if its implemented somewhere. The Parent class is abstract *and*
its vfn() is pure virtual. But be careful, if you don't provide an
access specifier (ie: Child_of_Parent::vfn(); ) you may be in for a
surprise (perhaps even a good surprise). Think GrandChild.
 
J

Jack Saalweachter

Peter_Julian said:
| Hi,
|
| Is it possible to force the typename of a template to inherit from a
| particular class? For example, something like this (conceptual; this
| doesn't compile):
|
| class Parent {
| public:
| [...]
| virtual void vfn() = 0;
| };
|
| template <child-of-Parent T>

you meant:

template< class Child_of_Parent >

or

template< typename Child_of_Parent >

| class CC {
| [...]
| void foo() {
| vfn();
| }
| };
|
| In other words, can I force T to be a child of Parent?
|

You already have set that requirement. The call to vfn() above is only
valid if its implemented somewhere. The Parent class is abstract *and*
its vfn() is pure virtual. But be careful, if you don't provide an
access specifier (ie: Child_of_Parent::vfn(); ) you may be in for a
surprise (perhaps even a good surprise). Think GrandChild.
That doesn't /quite/ work, because templates are perfectly happy to call
vfn's which aren't member functions in classes derived from Parent.

For instance:
class NotChild {
public:
void vfn() { /* !!! */ }
};

CC<NotChild> is perfectly valid and works just fine, even though it
doesn't derive from Parent.

Saying Child_of_Parent::vfn only works happily if you only have one
child of Parent. Otherwise, you have to template it and end up saying:
T bar;
bar.T::vfn();

Which doesn't really do anything.
 
K

Kaz Kylheku

Hi,

Is it possible to force the typename of a template to inherit from a
particular class? For example, something like this (conceptual; this
doesn't compile):

class Parent {
public:
[...]
virtual void vfn() = 0;
};

template <child-of-Parent T>
class CC {
[...]
void foo() {
vfn();
}
};

In other words, can I force T to be a child of Parent?

Why do you want to restrict what other people can do with your
template? That's their business.

The fact is that your template can be used in any situation which will
satisfy the generated call vfn() in the foo() function.

But I suspect you may be looking for a "mixin" template:

template <class T>
class CC : public T {
// ...
void foo { vfn(); }
}

Now T has to be a class, because it's used by inheritance. If the class
T has a function U vfn() where U is some type, possibly void, that
function will be inherited and used to satisfy the vfn() call.

T can be anything which has a vfn() function. If you have a non-member
vfn() function in scope, that can be used too! To prevent the use of a
file scope function, and insist on it coming from T, I think you can do
this:

void foo { T::vfn(); }

Beyond that, there is no need to restrict T to be a particular class.
 
B

blah

Hi,

Is it possible to force the typename of a template to inherit from a
particular class? For example, something like this (conceptual; this
doesn't compile):

class Parent {
public:
[...]
virtual void vfn() = 0;
};

template <child-of-Parent T>
class CC {
[...]
void foo() {
vfn();
}
};

In other words, can I force T to be a child of Parent?

Why do you want to restrict what other people can do with your
template? That's their business.

The fact is that your template can be used in any situation which will
satisfy the generated call vfn() in the foo() function.

You're absolutely right. I guess I didn't fully think the problem
through beforehand. I don't care what anyone else tries to do with
the template, I just want to be able to call vfn(). I just didn't
realize the compiler would let me do this. This will work fine.

Thanks everyone for your responses.
 

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,774
Messages
2,569,596
Members
45,135
Latest member
VeronaShap
Top