考虑这段代码:
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 下不起作用,给我:
error: conditional expression between distinct pointer types ‘Foo*’ and ‘Bar*’ lacks a cast Base* obj = !bar ? foo : bar;
这意味着要编译我必须将代码更改为:
Base* obj = !bar ? static_cast<Base*>(foo) : bar;
由于隐式转换为
Base*
存在,是什么阻止编译器这样做?换句话说,为什么
Base* obj = foo;
无需类型转换即可工作,但使用 ?:
运营商没有?是不是因为不清楚我要使用Base
部分?
最佳答案
引自 C++ 标准草案 N4296,第 5.16 节条件运算符,第 6.3 段:
- 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 段:
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:
- 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,“程序格式错误”。
以及第 4.10 节指针转换,第 3 段:
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 的指针不可相互转换(没有继承关系)。
关于c++ - 三元运算符隐式转换为基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62790856/