This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 110b. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2023-01-15


557. Does argument-dependent lookup cause template instantiation?

Section: 6.5.4  [basic.lookup.argdep]     Status: CD1     Submitter: Mike Miller     Date: 8 February 2006

[Voted into WP at the October, 2006 meeting.]

One might assume from 13.9.2 [temp.inst] paragraph 1 that argument-dependent lookup would require instantiation of any class template specializations used in argument types:

Unless a class template specialization has been explicitly instantiated (13.9.3 [temp.explicit]) or explicitly specialized (13.9.4 [temp.expl.spec]), the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program.

A complete class type is required to determine the associated classes and namespaces for the argument type (to determine the class's bases) and to determine the friend functions declared by the class, so the completeness of the class type certainly “affects the semantics of the program.”

This conclusion is reinforced by the second bullet of 6.5.4 [basic.lookup.argdep] paragraph 2:

A class template specialization is a class type, so the second bullet would appear to apply, requiring the specialization to be instantiated in order to determine its base classes.

However, bullet 8 of that paragraph deals explicitly with class template specializations:

Note that the class template specialization itself is not listed as an associated class, unlike other class types, and there is no mention of base classes. If bullet 8 were intended as a supplement to the treatment of class types in bullet 2, one would expect phrasing along the lines of, “In addition to the associated namespaces and classes for all class types...” or some such; instead, bullet 8 reads like a self-contained and complete specification.

If argument-dependent lookup does not cause implicit instantiation, however, examples like the following fail:

    template <typename T> class C {
        friend void f(C<T>*) { }
    };
    void g(C<int>* p) {
        f(p);    // found by ADL??
    }

Implementations differ in whether this example works or not.

Proposed resolution (April, 2006):

  1. Change bullet 2 of 6.5.4 [basic.lookup.argdep] paragraph 2 as indicated:

  2. Delete bullet 8 of 6.5.4 [basic.lookup.argdep] paragraph 2: