Title
Always-complete archetypes
Status
concepts
Section
_N2914_.14.11.2.1 [temp.archetype.assemble]
Submitter
James Widman

Created on 2008-11-28.00:00:00 last changed 186 months ago

Messages

Date: 2009-11-08.00:00:00

Suppose we have

    template<std::ObjectType T>
    T* f(T* p) {
         return ++p; // Presumably ok
    }

7.6.2.3 [expr.pre.incr] paragraph 1 requires that “The type of the operand shall be an arithmetic type or a pointer to a completely-defined effective object type.” At ++p in this example, the type archetype T' is considered to be completely-defined because

A type archetype is considered to be completely defined when it is established

(_N2914_.14.11.2.1 [temp.archetype.assemble] paragraph 1) and 13.9.3 [temp.explicit] paragraph 7 says that an archetype becomes established when

the archetype is used in a context where a complete type is required

So far, so good. Consider use of f(T*) with an incomplete type, for instance:

    struct A; // A is not defined yet.

    A* g(A* p) {
         return f(p);
    }

During template argument deduction against the template f(T*), we find that there is a concept map for std::ObjectType<A> because std::ObjectType is a compiler-supported concept, and because A is an object type (6.8 [basic.types]), so the compiler provides the concept map implicitly. Type deduction succeeds, but then we get an instantiation-time error on ++p because A is incomplete.

I see two potential solutions:

  1. We can remove built-in operations for ptr-to-effective-object-type, so that you would have to explicitly require something like std::HasPreincrement<T*> before using ++ on values of type T* in f(T*). Then A's lack of completeness would be indicated when we try to satisfy those requirements automatically (and not at instantiation time).

  2. Alternatively, we can introduce the notion of a compiler-supported concept std::CompleteType<T>, and amend _N2914_.14.11.2.1 [temp.archetype.assemble] so that a type archetype is only considered to be completely-defined if it has that requirement. This would imply that f(T*) above is ill-formed at ++p because T would then be an incomplete effective object type; the user could fix this by inserting requires std::CompleteType<T> after the template-parameter-list, and then the call f(p) would be ill-formed because std::CompleteType<A> would not be satisfied.

History
Date User Action Args
2009-08-03 00:00:00adminsetstatus: open -> concepts
2008-11-28 00:00:00admincreate