友元注入会格式错误吗?

Mec*_*hap 4 c++ templates friend language-lawyer c++23

标准中曾经有一段话指出:

除非在命名空间范围内显式声明,否则类模板特化的命名空间范围友元函数的名称在普通查找期间不可见。这些名称可以在相关类下找到。

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
}
Run Code Online (Sandbox Code Playgroud)

此功能已用于在编译时捕获和检索元编程状态。

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);
// ...
Run Code Online (Sandbox Code Playgroud)

据我所知,CWG 有一个问题旨在使此类行为变得不规范,尽管禁止此类行为的机制尚未确定。然而,由于最新草案中似乎没有该段落,我想知道友元注入在 C++23 中是否格式不正确。

Art*_*yer 7

来自P1787R6

将 [temp.inject] 合并到 [temp.friend]

( 2021 年 3 月N4885采用)

当前草案(N4901)内容为([temp.friend]p2):

友元类、类模板、函数或函数模板可以在类模板内声明。当模板被实例化时,它的友元声明是通过名称查找找到的,就好像专门化已在其实例化点显式声明一样

这似乎覆盖了旧的 [temp.inject]p2