標準中曾經有一段規定
除非在命名空間范圍內顯式宣告,否則類模板特化的命名空間范圍友元函式的名稱在普通查找期間不可見。這些名稱可以在關聯類下找到。
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
}
此功能已用于在編譯時捕獲和檢索元編程狀態。
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);
// ...
據我所知,CWG 提出了一個問題,旨在使此類行為不正常,盡管禁止此類行為的機制尚未確定。但是,由于最新草案中似乎沒有該段落,我想知道朋友注入在 C 23 中是否格式不正確。
uj5u.com熱心網友回復:
從P1787R6 開始:
將 [temp.inject] 合并到 [temp.friend]
(2021 年 3 月在N4885中采用)
當前草案 ( N4901 ) 為 ([temp.friend]p2):
友元類、類模板、函式或函式模板可以在類模板中宣告。當一個模板被實體化時,它的友元宣告是通過名稱查找找到的,就好像在它的實體化點已經顯式宣告了特化一樣
這似乎涵蓋了舊的 [temp.inject]p2
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/427995.html
上一篇:JetpackCompose底部導航欄可見性隨延遲而變化
下一篇:傳遞引數包重復運行
