Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Will friend injections be ill-formed?

There used to be a paragraph in the standard which stated that

the names of a namespace-scope friend functions of a class template specialization are not visible during an ordinary lookup unless explicitly declared at namespace scope. Such names may be found under for associated classes.

template <typename T> struct number {
    number(int);
    friend number gcd(number x, number y) { return 0; }
};

void g() {
    number<double> a(3), b(4);
    a = gcd(a, b);    // finds gcd becuase numer<double> is an associated class,
                      // making gcd visible in its namespace (global scope)
    b = gcd(3, 4);    // error: gcd is not visible
}

This feature has been used to capture and retrieve a metaprogramming state at compile time.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

template <int X>
struct flag {
    friend consteval int f(flag<X>);
};

template <int X, int N>
struct injecter {
    friend consteval int f(flag<X>) { return N; }
};

template <int N = 0, auto = []{}>
consteval auto inject() {
    if constexpr (requires { f(flag<X>{}); }) {
        return inject<N+1>();
    } else {
        void(injecter<X>{});
        return f(flag<X>{});
    }
}

static_assert(inject() == 0);
static_assert(inject() == 1);
static_assert(inject() == 2);
static_assert(inject() == 3);
// ...

As far as I know, there is an issue from CWG which aimed to make such behaviour ill-formed although the mechanism for prohibiting them is as yet undetermined. However, as the paragraph seems to be absent from the latest draft, I’m wrondering if friend injections will be ill-formed in C++23.

>Solution :

From P1787R6:

Merged [temp.inject] into [temp.friend]

(Adopted in N4885 in March 2021)

The current draft (N4901) reads ([temp.friend]p2):

Friend classes, class templates, functions, or function templates can be declared within a class template.
When a template is instantiated, its friend declarations are found by name lookup as if the specialization had
been explicitly declared at its point of instantiation

Which seems to cover the old [temp.inject]p2

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading