cho*_*tte 13 c++ templates overload-resolution
我有类似的东西:
#include <iostream>
class Foo;
struct Test
{
template <typename T>
operator T() const // <----- This const is what puzzles me
{
std::cout << "Template conversion" << std::endl;
return T{};
}
operator Foo*()
{
std::cout << "Pointer conversion" << std::endl;
return nullptr;
}
};
int main()
{
Test t;
if (t)
{
std::cout << "ahoy" << std::endl;
}
bool b = (bool)t;
Foo* f = (Foo*)t;
}
Run Code Online (Sandbox Code Playgroud)
它构建良好,但当我运行它,而我期望得到
$> ./a.out
Template conversion
Template conversion
Pointer conversion
Run Code Online (Sandbox Code Playgroud)
我反而得到了
$> ./a.out
Pointer conversion
Pointer conversion
Pointer conversion
Run Code Online (Sandbox Code Playgroud)
如果我删除const,或使Test实例为const,那么一切都按预期工作.更确切地说,当两个运算符具有相同的const限定时,过载选择似乎是有意义的.
13.3.3.1.2标准的要点让我觉得我应该得到一个身份转换,转换为bool,使用带有T= 的模板转换运算符实例化bool,虽然显然有一个隐藏在某处的微妙.有人可以告诉我这里有什么规则发挥作用吗?
相关规则在[over.match.best]中定义:
给定这些定义,如果对于所有参数i,可行函数
F1被定义为比另一个可行函数更好的函数 ,ICS i()不是比ICS i()更差的转换序列,然后是 (1.3) - 对于某些参数j,ICS j()是比ICS j()更好的转换序列,或者,如果不是, (1.4) - 上下文是用户定义的转换初始化(见8.5,13.3.1.5和13.3.1.6)和从返回类型到目标类型的标准转换序列(即,正在初始化的实体的类型)是比从返回类型到目标类型的标准转换序列更好的转换序列.F2F1F2F1F2F1F2
我们来看看第一个bool案例.我们有两个可行的候选人:
Test::operator T<bool>() const;
Test::operator Foo*();
Run Code Online (Sandbox Code Playgroud)
两者都用非调用const Test.对于第二次重载,不需要转换 - 转换序列只是完全匹配.但是,对于第一个重载,隐式this参数需要经历从Test到的限定转换const Test.因此,第二个重载是首选 - 我们没有进入讨论返回类型的第二步.
如果我们放弃了const,那么可行的候选人将成为:
Test::operator T<bool>();
Test::operator Foo*();
Run Code Online (Sandbox Code Playgroud)
在这里,这两个候选者是具有相同转换序列同样可行,但bool由于从返回类型转换序列模板优选bool以bool(认同-最高等级)比从更好的转换序列Foo*,以bool(布尔转换-最低).
比较转换序列时,会先考虑参数的转换,然后再考虑结果类型的转换。隐式对象参数(this指针)被视为参数,并且限定转换(Foo -> Foo const)比隐式对象参数上的恒等转换差。来自[over.match.best]:
\n\n\n1 - [...] 可行函数 F1 被定义为比另一个可行函数更好的函数\n F2 如果对于所有参数 i,ICSi(F1) 不是比 ICSi( 更差的转换序列F2),然后
\n\n\xe2\x80\x94 对于某些参数 j,ICSj(F1) 是比 ICSj(F2) 更好的转换序列,或者,如果不是这样,[...]
\n
因此,非const限定成员转换运算符总是比const限定的成员转换运算符更好,即使后者的转换结果是精确的。
| 归档时间: |
|
| 查看次数: |
134 次 |
| 最近记录: |