Overloading static and non-static member function with constraint(使用约束重载静态和非静态成员函数)
问题描述
此代码有效吗?
template<bool b>
struct s {
void f() const {
}
static void f() requires b {
}
};
void g() {
s<true>().f();
}
啪的一声说是,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
https://godbolt.org/z/f4Kb68aee
推荐答案
如果我们通过[over.match.best.general],我们将获得:
一个可行函数
F1
被定义为比另一个可行函数F2
好的函数,如果对于所有参数i
,ICSi(F1)
不是比ICSi(F2)
更差的转换序列,然后[...]
唯一的参数是Object参数,我们在前面有过:
因此前提成立:一个函数的所有参数的转换序列不比另一个函数的转换序列差。所以我们进入决胜局...如果
F
是静态成员函数,则ICS1(F)
被定义为对于任何函数ICS1(F)
既不比ICS1(G)
好也不比ICS1(G)
差,并且对称地,ICS1(G)
既不比ICS1(F)
好也不比ICS1(F)
差;否则
我们可以有更好的转换序列的唯一参数是对象参数,正如所确定的那样,该参数是等价的。因此,此决胜局不适用。
- 对于某些参数
j
,ICSj(F1)
是比ICSj(F2)
更好的转换序列,如果不是这样,
- 上下文是通过用户定义的转换(参见[dcl.init]、[over.match.conv]和[over.match.ref])和[...]
进行的初始化
没有。
- 上下文是转换函数的初始化,用于直接引用绑定到函数类型的引用,[...]
没有。
F1
不是函数模板专门化,F2
是函数模板专门化,否则
没有。
F1
和F2
是函数模板专门化,根据[temp.unc.order]中描述的偏序规则,F1
的函数模板比F2
的模板专门化,如果不是这样,
没有。
F1
和F2
是具有相同参数类型列表的非模板函数,根据[temp.constr.order]中描述的约束的部分顺序,F1
比F2
更受约束,如果不是这样,
啊哈!在本例中,我们的非模板函数具有相同的参数类型列表(两者都是空的)。静态成员函数受约束,而非静态成员函数不受约束,这是受约束程度最低的一种(请参阅[temp.constr.order])。
因此,我认为Cang(和MSVC)接受这个计划是正确的,GCC拒绝它是错误的。(已提交103783)。这篇关于使用约束重载静态和非静态成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用约束重载静态和非静态成员函数
基础教程推荐
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- C++,'if' 表达式中的变量声明 2021-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 设计字符串本地化的最佳方法 2022-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17