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中对此问题的详细讨论可能更好.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...