c++language-lawyer

How does auto return type affect a name lookup?


In the following example if you change auto to void the program will print 1 instead of 0. Why is that happening. What lookup rules are applicable here?

#include <iostream>

struct X { operator int() const; };

std::false_type f(int);

template <typename T>
auto f2(T t) {
    std::cout << decltype(f(t)){};
}

decltype(f2(X{}))*_;

std::true_type f(X);


int main() {
    f2(X{});
}

live example


Solution

  • Switching the return type between void and auto changes whether decltype(f2(X{})) performs the implicit instantiation of f2.

    When the return type is spelled out as void, the declaration is sufficient; the definition doesn't need to be instantiated. Then f2<X> has one point of instantiation - at the end of the translation unit, right after main. At this point, the two overfloads of f are visible, and f(X) is chosen as a better match.

    When the return type is auto, the definition needs to be instantiated. Then f2<X> has two points of instantiation - one after main, and an extra one at the decltype line. Now, different points of instantiation give the template specialization different meanings, at which point the program is ill-formed, no diagnostic required. Apparently, your implementation happens to choose the first point of instantiation, where only one f overload is visible.


    [temp.point]/1 For a function template specialization ... the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization.

    [temp.point]/8 A specialization for a function template ... may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above, for any such specialization that has a point of instantiation within the translation unit, the end of the translation unit is also considered a point of instantiation... If two different points of instantiation give a template specialization different meanings according to the one-definition rule (6.2), the program is ill-formed, no diagnostic required.