Dav*_*one 9 c++ language-lawyer c++-concepts c++20
该代码有效吗?
template<bool b>
struct s {
void f() const {
}
static void f() requires b {
}
};
void g() {
s<true>().f();
}
Run Code Online (Sandbox Code Playgroud)
clang 说是,但 gcc 说不
<source>: In function 'void g()':
<source>:10:20: error: call of overloaded 'f()' is ambiguous
10 | s<true>().f();
| ~~~~~~~~~~~^~
<source>:3:14: note: candidate: 'void s<b>::f() const [with bool b = true]'
3 | void f() const {
| ^
<source>:5:21: note: candidate: 'static void s<b>::f() requires b [with bool b = true]'
5 | static void f() requires b {
| ^
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)
如果我们通过[over.match.best.general],我们会得到:
如果对于所有参数,一个可行函数被定义为比另一个可行函数更好的函数,则转换序列不比 更差,然后 [...]
F1F2iICSi(F1)ICSi(F2)
唯一的参数是对象参数,我们之前有:
如果
F是静态成员函数,则定义为既不比任何函数更好也不比 更差,并且对称地,既不比 更好也不差;否则,ICS1(F)ICS1(F)ICS1(G)GICS1(G)ICS1(F)
因此,前提成立:一个函数的所有参数的转换序列不比另一个函数的转换序列差。所以我们继续我们的决胜局......
- 对于某些参数
j,是比 , 更好的转换序列,或者,如果不是这样,ICSj(F1)ICSj(F2)
我们可以为其提供更好的转换序列的唯一参数是对象参数,并且正如所确定的那样,该参数是等效的。所以这个决胜局不适用。
- 上下文是通过用户定义的转换进行的初始化(请参阅 [dcl.init]、[over.match.conv] 和 [over.match.ref])和 [...]
没有。
- 上下文是通过转换函数进行初始化,用于对函数类型的引用进行直接引用绑定,[...]
没有。
F1不是函数模板专业化,而是F2函数模板专业化,或者,如果不是这样,
没有。
F1和F2是函数模板特化,并且根据 [temp.func.order] 中描述的部分排序规则,函数F1模板比模板更特化,或者,如果不是这样,F2
没有。
F1和F2是具有相同参数类型列表的非模板函数,并且比 [temp.constr.order] 中描述的约束的部分排序F1受到更多约束F2,或者如果不是这样,
啊哈!在这个例子中,我们有具有相同参数类型列表的非模板函数(两者都是空的)。静态成员函数受约束,非静态成员函数不受约束,这是最简单的一种“更多约束”(请参阅 [temp.constr.order])。
因此,我认为 clang (和 msvc)接受该程序是正确的,而 gcc 拒绝它是错误的。(提交103783)。
| 归档时间: |
|
| 查看次数: |
247 次 |
| 最近记录: |