User:Decltype/Concepts

In C++, template classes and functions necessarily impose restrictions on the types that they take. For instance, the standard library containers require that the contained types be assignable. Unlike the dynamic polymorphism that class inheritance hierarchies exhibit, where a function that accepts an object of type  can be passed any subtype of , any class can be supplied as a template parameter so long as it supports all of the operations that the template uses. In the case of the function, the requirement an argument must meet is clear (being a subtype of ), but in the case of a template the interface an object must meet is implicit in the implementation of that template. Concepts provide a mechanism for codifying the interface that a template parameter must meet.
 * In July 2009, the C++ standards committee decided to remove concepts from C++0x. This section documents concepts as they are described in the latest published working paper .

The primary motivation of the introduction of concepts is to improve the quality of compiler error messages. If a programmer attempts to use a type that does not provide the interface a template requires, the compiler will generate an error. However, such errors are often difficult to understand, especially for novices. There are two main reasons for this. First, error messages are often displayed with template parameters spelled out in full; this leads to extremely large error messages. On some compilers, simple errors can generate several kilobytes of error messages. Second, they often do not immediately refer to the actual location of the error. For example, if the programmer tries to construct a  of objects that do not have a copy constructor, the first error almost always refers to the code within the   class itself that attempts to copy construct its contents; the programmer must be skilled enough to understand that the real error was that the type doesn't support everything the   class requires.

In an attempt to resolve this issue, C++0x adds the language feature of concepts. Similar to how OOP uses a base-class to define restrictions on what a type can do, a concept is a named construct that specifies what a type must provide. Unlike OOP, however, the concept definition itself is not always associated explicitly with the type being passed into the template, but with the template definition itself:

Rather than using an arbitrary  or   for the template type parameter, it uses , which is a concept that was previously defined. If a type passed into the  template function does not satisfy the requirements of the   concept, then a compile error will result, telling the user that the type used to instantiate the template does not fit the   concept.

A more generalized form of the concept is as follows:

The keyword  begins a list of requirements, which are specified by concept(s). In the requirement list, multiple concepts can be combined with boolean operation negative(!) and logical-and(&&) to form template constraint. Using the syntax of  if the user wishes to prevent the use of one particular template if the type matches the concept. This mechanism can be used in a way similar to template specialization. A general template would handle types with fewer features, explicitly disallowing the use of other, more feature-rich, concepts. And those concepts would have their own specializations that use those particular features to achieve greater performance or some other functionality. Another operation logical-and is also easy to use in the requirement list. For the type used in the template requires both assignment and copy-construct, just add.

Concepts are defined as follows:

The keyword, in this instance, means that any type that supports the operations specified in the concept will be considered to support the concept. Without the use of the  keyword, the type must use a concept map in order to declare itself as supporting the concept.

This concept says that any type that has an  that takes two objects of that type and returns a   will be considered. The operator need not be a free-function; it could be a member function of the type.

Concepts can involve multiple objects as well. For example, concepts can express that a type is convertible from one type to another:

In order to use this in a template, it must use a generalized form of concept usage:

Concepts may be composed. For example, given a concept named :

The first template parameter to the  concept must conform to the   concept.

Concepts can also be derived from one another, like inheritance. Like in class inheritance, types that meet the requirements of the derived concept also meet the requirements of the base concept. It is defined as per class derivation:

Typenames can also be associated with a concept. These impose the requirement that, in templates that use those concepts, these typenames are available:

Concept maps allow types to be explicitly bound to a concept. They also allow types to, where possible, adopt the syntax of a concept without changing the definition of the type. As an example:

This map fills in the required typenames for the  concept when applied to   types.

As an added degree of flexibility, concept maps themselves can be templated. The above example can be extended to all pointer types:

Further, concept maps can act as mini-types, with function definitions and other constructs commonly associated with classes:

This concept map allows templates that take types that implement the concept  to take a , remapping the function calls directly to the   calls. Ultimately, this allows a pre-existing object to be converted, without touching the definition of the object, into an interface that a template function can utilize.

Finally, it should be noted that some requirements can be checked using static assertions. These can verify some requirements that templates need, but are really aimed at a different problem.

Axioms
Axioms are a facility pertaining to concepts supplied by C++0x to express the semantic properties of concepts. For example, the concept  can be defined with an axiom   as

Compilers are allowed, but not required, to take advantage of the semantics specified by axioms to perform optimizations that possibly have side-effects on the observable behavior of the program, which are typically prohibited (with few exceptions such as copy constructor elision). In the above example, compilers may reassociate nested calls to  of type   on several values of type   provided that there is a concept map for types   and   to the concept.

Axioms can also assist in software verification, software testing, and other program analyses and transformations.