Title
Questions regarding the point of definition of a concept map
Status
concepts
Section
_N2914_.14.10.2 [concept.map]
Submitter
James Widman

Created on 2009-02-10.00:00:00 last changed 179 months ago

Messages

Date: 2009-11-08.00:00:00
  1. According to _N2914_.14.11.1.1 [temp.req.sat] paragraph 2, a concept requirement is satisfied if a concept map with the same name and template argument list is found by concept map lookup. The point at which the name of a concept map is inserted into its scope is, according to _N2914_.14.10.2 [concept.map] paragraph 2, immediately following its concept-id. This enables a requirement on a member of a concept map to be satisfied by the concept map in which it appears, for example:

        concept C2<typename T>{}
    
        concept D2<typename T> {
                typename type;
                requires C2<type>;
        }
    
        template<D2 T>
        concept_map C2<T>{}
    
        concept_map D2<int> {
                typedef int type; // Okay
        }
    

    However, these rules might lead to problems with the concept maps that the compiler tries but fails to generate for auto concepts. Presumably a compiler might insert the name of the generated concept map into the containing scope, so that it can satisfy its own requirements, but then if some other requirement cannot be satisfied and thus the concept map is not defined after all (_N2914_.14.10.2 [concept.map] paragraph 11), the name must then be removed again. It might be clearer to make the point of definition for a concept map after the closing brace and just have a special case for how the concept map is handled within its own definition.

  2. On a related note, the current specification seems unclear about whether a failure to generate a concept map for an auto concept means that no further attempts will be made to generate it. Consider the following example:

        auto concept A<typename X> { /* */ }
        auto concept B<typename X> : A<X> { void enabler(X); }
    
        template <A T> void f(T x); // #1
        template <B T> void f(T x); // #2
    
        class C
        {
           // a class that satisfies A<C> but not B<C>
           // because no enabler(X) in scope
        };
    
        int foo()
        {
           C x;
           f(x); // #3
        }
    
        void enabler(C);
    
        int bar()
        {
           C x;
           f(x); // #4
        }
    

    At #3, the concept map for B cannot be generated, so the call invokes #1. There doesn't appear to be anything currently that indicates that the reference at #4 should not once again attempt to generate the concept map for B, which will succeed this time and make the call invoke #2. It seems preferable that both calls should invoke #1, but that does not seem to be the effect of the current wording.

History
Date User Action Args
2009-08-03 00:00:00adminsetstatus: open -> concepts
2009-02-10 00:00:00admincreate