C++ template parameter constraints
Martin Buchholz
martin@xemacs.org
Sun Feb 2 18:06:00 GMT 2003
>>>>> "A" == Alexandre Oliva <aoliva@redhat.com> writes:
A> On Jan 30, 2003, Martin Buchholz <martin@xemacs.org> wrote:
>> http://m17n.org/martin/writings/template-parameter-constraints.html
>> (feedback desired)
A> /me thinks the syntax for satisfying might be something like Modula3's
A> `T1 < T2' constraint, used to indicate that type T1 must be the same
As I say elsewhere, I don't like `T1 < T2' because I would like to
express arbitrary compile-time constraints.
A> or derived from T2. We could use something like:
A> template <class T : predicate<T>::satisfied> declaration;
I don't think the constraint belongs within the <...> template
parameter list, because the constraints apply potentially to ALL the
template parameters, i.e. a template constraint may not be naturally
associated with a particular template parameter. Standard example is
again `T1 is a subclass of T2'.
A> and then define the predicate template in such a way that satisfied is
A> typedefed to T if T satisfies the predicate, and not defined at all
A> otherwise.
Yes.
A> Another addition that I'd find useful for template meta-programming is
A> an operator such as :?:, similar to :: but with the following
A> additional properties:
A> - its left-hand operand must be a template-dependent type name
A> - if the address of an expression containing :?: is taken and it turns
A> out that, for a particular instantiation of the template, the member
A> does not exist, the result is NULL
I would prefer a more general solution. I imagine a C++ compile-time
function something like
is_compilable<Type, ...> ({ declarations ... ;;; code ... })
You could then ask
is_compilable<T> ({ T x; T y ;;; x < y; })
is_compilable<T> ({ T x; T y ;;; x == y; })
is_compilable<T> ({ T x; ;;; hash (x); })
to decide at compile time whether to use a linked list, a binary tree,
or a hash table to implement a `set<T>' data type, without the user
having to create a special traits class to help out.
A> - a typename expression containing :?: that refers to a type member
A> that does not exist in a given template name resolves to a new C++
A> type that, in the absence of a better name, will be called
A> nosuchtype.
A> - sizeof applied to nosuchtype is zero
A> - Any typename expression referencing members of nosuchtype resolve
A> to nosuchtype
A> - Any expression involving data members of nosuchtype has type
A> nosuchtype, and translates to a call of terminate()
A> - Any expression involving function members of nosuchtype (operator
A> functions included) succeed overload resolution, but performing the
A> actual function call evaluates the arguments and calls terminate().
A> The idea is that such constructs be guarded by NULL- or zero-size
A> tests and be optimized away, but still parse correctly.
A> Comments?
Compile-time reflection in C++ is incredibly useful, as is shown by
the enormous efforts being applied to implement and use it. The C++
committee has to recognize that C++ is now a language with a
compile-time MOP, like OpenC++. But the current MOP is limited and
amazingly kludgy. A small number of extensions to C++ can probably
fix that. Finding the appropriate extensions to enable that will be
difficult.
Being able to ask the compiler whether a piece of code is compilable
might be a generalization of your idea above. Of course, if you
introduce something like is_compilable, people will want to
distinguish among different kinds of compile failures.
Currently, boost's is_base_and_derived causes a compile error if
private inheritance is used. Implementors of is_base_and_derived
would want to have something like is_compilable, but they might also
want to know WHY something is or is not compilable.
More information about the Gcc
mailing list