Created on 2008-11-28.00:00:00 last changed 186 months ago
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:
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).
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:00 | admin | set | status: open -> concepts |
2008-11-28 00:00:00 | admin | create |