三元运算符隐式转换为基类 [英] Ternary operator implicit cast to base class

查看:128
本文介绍了三元运算符隐式转换为基类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这段代码:

struct Base
{
    int x;
};

struct Bar : Base
{
    int y;
};

struct Foo : Base
{
    int z;
};

Bar* bar = new Bar;
Foo* foo = new Foo;

Base* returnBase()
{
    Base* obj = !bar ? foo : bar;
    return obj;
}

int main() {
    returnBase();
    return 0;
}

这在Clang或GCC下不起作用,给我:

This doesn't work under Clang or GCC, giving me :


错误:不同指针类型'Foo *'
和'Bar *'之间的条件表达式缺少强制转换的Base * obj =!bar? foo:bar;

error: conditional expression between distinct pointer types ‘Foo*’ and ‘Bar*’ lacks a cast Base* obj = !bar ? foo : bar;

这意味着要编译,我必须将代码更改为:

Which means for it to compile I have to change the code to :

Base* obj = !bar ? static_cast<Base*>(foo) : bar;

因为隐式强制转换为 Base * 存在,是什么阻止了编译器这样做?

Since an implicit cast to a Base* exists, what is preventing the compiler from doing so?

换句话说,为什么 Base * obj = foo; 无需强制转换但可以使用?:运算符来工作吗?是因为不清楚我是否要使用 Base 部分?

In other words, why does Base* obj = foo; work without a cast but using the ?: operator doesn't? Is it because it's not clear that I want to use the Base part?

推荐答案

引用C ++标准草案N4296第5.16节有条件的运算符 第6.3段:

Quoting from C++ standard draft N4296, Section 5.16 Conditional operator, Paragraph 6.3:



  • 第二和第三操作数中的一个或两个具有指针类型;进行了指针转换(4.10)和
    资格转换(4.4) ,以将其转换为复合指针类型(第5条)。
    结果是复合指针类型。

  • One or both of the second and third operands have pointer type; pointer conversions (4.10) and qualification conversions (4.4) are performed to bring them to their composite pointer type (Clause 5). The result is of the composite pointer type.

第5节表达式,第13.8和13.9段:

Section 5 Expressions, Paragraph 13.8 and 13.9:


两个分别具有T1和T2类型的操作数p1和p2的复合指针类型,在
处,至少有一个是指向成员类型或std :: nullptr_t的指针或指针,是:

The composite pointer type of two operands p1 and p2 having types T1 and T2, respectively, where at least one is a pointer or pointer to member type or std::nullptr_t, is:


  • 如果T1和T2是类似的类型(4.4),T1和T2的cv组合类型;

  • 否则,需要确定复合指针类型的程序格式错误

  • if T1 and T2 are similar types (4.4), the cv-combined type of T1 and T2;
  • otherwise, a program that necessitates the determination of a composite pointer type is ill-formed.

注意:我在这里复制5 / 13.8只是为了向您展示它没有打。实际上是5 / 13.9,程序格式错误。

Note: I copied 5/13.8 here just to show you that it doesn't hit. What's actually in effect is 5/13.9, "the program is ill-formed".

第4.10节指针转换,第3段:

And Section 4.10 Pointer conversions, Paragraph 3:


类型为 pointer to cv D的prvalue(其中D是类类型)可以转换为类型为 pointer $的prvalue b $ b到Cv B,其中B是D的基类(第10条)。如果B是D的不可访问(第11条)或模棱两可(10.2)
,则该程序需要进行此转换格式不正确。转换的结果是指向派生类对象的基类子对象的
指针。空指针值将转换为目标类型的
空指针值。

A prvalue of type "pointer to cv D", where D is a class type, can be converted to a prvalue of type "pointer to cv B", where B is a base class (Clause 10) of D. If B is an inaccessible (Clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type.

因此,没关系(完全)Foo和Bar都源自一个相同的基类。唯一重要的是,指向Foo的指针和指向Bar的指针不能相互转换(没有继承关系)。

So, it doesn't matter (at all) that both Foo and Bar are derived from one same base class. It only matters that a pointer to Foo and a pointer to Bar are not convertible to each other (no inheritance relationship).

这篇关于三元运算符隐式转换为基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆