1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
Sometimes templates must use sub-types of template types. Examples are
templates assuming the existence of tt(iterator) (like
tt(vector<int>::iterator)) or tt(value_type) which is used when calling
tt(std::push_back).
To specify that a sub-type must be available the concept's tt(requires)
specification needs no parameters, but can directly refer to the subtype. It's
also possible to combine type requirements with requirements that em(do)
define a non-empty parameter list, and so the tt(requires's) parameter list
does not em(have) to be empty. Here is a concept that specifies a plain type
requirement:
verb( template <typename Type>
concept HasValueType =
requires()
{
typename Type::value_type;
};)
and here's a concept that combines a simple requirement with a type
requirement:
verbinsert(-s4 //type examples/type.cc)
Calling tt(iter) with a tt(string) argument succeeds, calling it with a
tt(queue) argument results in two error notes: no tt(Type::iterator) and no
tt(tp.begin()).
Types specified in type requirements don't necessarily have to refer to
em(types). They may also specify be the names of nested classes or
enumerations defined by tt(Type). When specifying enumerations they do not
have to be strongly typed.
|