In Java you can define generic class that accept only types that extends class of your choice, eg:
public class ObservableList<T extends List> {
...
}
This is done using "extends" keyword.
Is there some simple equivalent to this keyword in C++?
As far as I know this isn't currently possible in C++. However, there are plans to add a feature called "concepts" in the new C++0x standard that provide the functionality that you're looking for. This Wikipedia article about C++ Concepts will explain it in more detail.
I know this doesn't fix your immediate problem but there are some C++ compilers that have already started to add features from the new standard, so it might be possible to find a compiler that has already implemented the concepts feature.
The simple solution, which no one have mentioned yet, is to just ignore the problem. If I try to use an
int
as a template type in a function template that expects a container class such as vector or list, then I will get a compile error. Crude and simple, but it solves the problem. The compiler will try to use the type you specify, and if that fails, it generates a compile error.The only problem with that is that the error messages you get are going to be tricky to read. It is nevertheless a very common way to do this. The standard library is full of function or class templates that expect certain behavior from the template type, and do nothing to check that the types used are valid.
If you want nicer error messages (or if you want to catch cases that wouldn't produce a compiler error, but still don't make sense) you can, depending on how complex you want to make it, use either Boost's static assert or the Boost concept_check library.
With an up-to-date compiler you have a built_in
static_assert
, which could be used instead.An equivalent that only accepts types T derived from type List looks like
I suggest using Boost's static assert feature in concert with
is_base_of
from the Boost Type Traits library:In some other, simpler cases, you can simply forward-declare a global template, but only define (explicitly or partially specialise) it for the valid types:
[Minor EDIT 6/12/2013: Using a declared-but-not-defined template will result in linker, not compiler, error messages.]
Well, you could create your template reading something like this:
This will however make the restriction implicit, plus you can't just supply anything that looks like a list. There are other ways to restrict the container types used, for example by making use of specific iterator types that do not exist in all containers but again this is more an implicit than an explicit restriction.
To the best of my knowledge a construct that would mirror the statement Java statement to its full extent does not exist in current standard.
There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.
In C++11, the introduction of concepts should make this easier but I don't think it'll do exactly what you'd want either.
We can use
std::is_base_of
andstd::enable_if
:(
static_assert
can be removed, the above classes can be custom-implemented or used from boost if we cannot referencetype_traits
)