微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 如何确定隐式类型转换优先级?

这是代码
class A{
public:
    int val;
    char cval;
    A():val(10),cval('a'){ }
    operator char() const{ return cval; }
    operator int() const{ return val; }
};
int main()
{
    A a;
    cout << a;
}

我在VS 2013中运行代码,输出值为10,如果我注释掉运算符int()const {return val; },输出值将成为a.

我的问题是编译器如何确定选择哪种隐式类型转换,我的意思是因为int和char都是<<操作符?

解决方法

是的,这是模棱两可的,但模棱两可的原因实际上是相当令人惊讶的.并不是编译器无法区分ostream :: operator<<(int)和operator<<(ostream&,char);后者实际上是一个模板,而前者不是,所以如果匹配同样好,第一个将被选中,并且这两个之间没有歧义.相反,模糊性来自ostream的其他成员操作符<<重载. 一个 minimized repro
struct A{
    operator char() const{ return 'a'; }
    operator int() const{ return 10; }
};

struct B {
    void operator<< (int) { }
    void operator<< (long) { }
};

int main()
{
    A a;
    B b;
    b << a;
}

问题是a转换为long可以通过a.operator char()或a.operator int(),然后是一个由整数转换组成的标准转换序列.标准说(§13.3.3.1[over.best.ics] / p10,脚注省略):

If several different sequences of conversions exist that each convert
the argument to the parameter type,the implicit conversion sequence
associated with the parameter is defined to be the unique conversion
sequence designated the ambiguous conversion sequence. For the
purpose of ranking implicit conversion sequences as described in
13.3.3.2,the ambiguous conversion sequence is treated as a user-defined sequence that is indistinguishable from any other
user-defined conversion sequence. *

由于a到int的转换也涉及用户定义的转换序列,因此它与从a到long的模糊转换序列无法区分,并且在此上下文中,§13.3.3[over.match.best]中没有其他规则适用于区分这两个过载.因此,呼叫是模糊的,程序是不正确的.

*标准中的下一句话说“如果选择使用模糊转换序列的函数作为最佳可行函数,则调用将是格式错误的,因为调用中某个参数的转换是不明确的.”,看起来不一定正确,但在separate question中对此问题的详细讨论可能更好.

原文地址:https://www.jb51.cc/c/119749.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐