【发布时间】:2022-11-25 06:47:57
【问题描述】:
考虑以下代码,其中类 A 具有嵌套类型 B,模板成员函数包含尾随 requires 子句命名嵌套类型 B,随后在类外定义:
template <typename X, typename Y>
concept C = true;
struct A
{
struct B {};
template <typename T>
void f1()
requires C<T, A::B>;
template <typename T>
void f2()
requires C<T, A::B>;
template <typename T>
void f3()
requires C<T, B>;
template <typename T>
void f4()
requires C<T, B>;
};
template <typename T>
inline void A::f1()
requires C<T, A::B> {}
template <typename T>
inline void A::f2()
requires C<T, B> {}
template <typename T>
inline void A::f3()
requires C<T, A::B> {}
template <typename T>
inline void A::f4()
requires C<T, B> {}
int main()
{
A{}.f1<A::B>();
A{}.f2<A::B>();
A{}.f3<A::B>();
A{}.f4<A::B>();
}
我一直无法找到/理解关于是否:
- 尾随 requires 子句可以以类似于尾随返回类型的方式命名嵌套类型而无需显式限定
-
f2、f3和f4中的哪一个,如果有的话,应该被一致的实现所接受
我能在标准草案中找到的最接近的是 [temp.mem],
在其类模板定义之外定义的类模板的成员模板应指定一个与类模板等效的模板头,后跟一个与成员模板等效的模板头(13.7.6.1)。
13.7.6.1 在第 7 段中引用 [temp.over.link],
如果两个函数模板在同一范围内声明,具有相同的名称,具有等效的模板头,并且具有使用上述规则等效的返回类型、参数列表和尾随要求子句(如果有),则它们是等效的比较涉及模板参数的表达式。
就 requires 子句本身而言,等效性似乎由
它们都有 requires-clauses 并且相应的约束表达式是等价的。
在任何其他情况下,我希望
f1到f4中的所有形式的约束都是(正式的)相等的,但我对标准还不够熟悉,无法为自己得出结论。在实现方面,clang 和 gcc 似乎始终接受所有定义,而 MSVC 不同,并且最近在行为上发生了变化:
Function gcc 12.2 clang 15.0.0 MSVC 19.33 MSVC Latest (19.34?) f1Accepted Accepted Accepted Accepted f2Accepted Accepted error C2244: 'A::f2': unable to match function definition to an existing declaration error C2244: 'A::f2': unable to match function definition to an existing declaration f3Accepted Accepted error C2244: 'A::f3': unable to match function definition to an existing declaration error C2244: 'A::f3': unable to match function definition to an existing declaration f4Accepted Accepted Accepted error C2065: 'B': undeclared identifier
【问题讨论】:
-
可以在函数参数和 noexcept 说明符中使用不合格的
B(在模板和非模板中),我不明白为什么 requires 子句应该有任何不同。但我找不到标准在哪里这么说。 -
@n.m.我认为那部分应该由 eel.is/c++draft/basic.scope.class#1.sentence-2 处理,它在声明者编号在类的范围内。但是是否考虑
C<T, A::B>和C<T, B>相等的对我来说似乎不太清楚。 -
在什么意义上它们可以是不等价的?
-
@n.m.根据 [temp.over.link] 中规定的规则。我试图尽我所能给出答案。
标签: c++ c++20 c++-concepts