Aar*_*aid 10 c++ casting ternary-operator
这段代码的最后一行无法编译 castingAndTernary.cpp:15: error: conditional expression between distinct pointer types ‘D1*’ and ‘D2*’ lacks a cast
一个非常聪明的编译器可以没有任何困难,因为它们都可以安全地转换为B*(基类).我不愿意使用static_cast和dynamic_cast等等 - 我担心有一天我会混淆这些类并获得未定义的行为.这就是我创建up_cast模板的原因.此模板在允许的转换中完成了最低限度.有更简单的方法吗?还有其他的解决方法,但我不禁想到,我可以使用更简单,更安全的东西吗?
struct B{ };
struct D1 : public B{ };
struct D2 : public B{ };
template<typename T,typename V>
T up_cast(V x) {
return x;
}
int main() {
bool boolean_expression = true;
B * b;
b = new D1;
b = new D2;
b = boolean_expression ? up_cast<B*>(new D1) : up_cast<B*>(new D2);
b = boolean_expression ? new D1 : new D2;
}
Run Code Online (Sandbox Code Playgroud)
g ++(Ubuntu 4.3.3-5ubuntu4)4.3.3
更新从更名implicit_cast到up_cast按@康拉德的回答
一个非常聪明的编译器可以没有任何困难,因为两者都可以安全地转换为
B*
无关紧要.该标准规定了这种行为.一个非常聪明的编译器就像观察到的一样
使用你的自定义演员实际上很好(你不愿意使用显式演员阵容).但是,我使用了一个不同的名称:upcast- 因为这发生在:继承层次结构中的向上转换.
我不打算回答,但在发表评论后我想,这是什么......这是一种方法,就像其他任何方法一样:
int main() {
bool condition = true;
D1 d1;
D2 d2;
B * p = condition ? &d1 : (true? &d2 : p );
}
Run Code Online (Sandbox Code Playgroud)
基本上滥用三元运算符来提取适当的类型.当编译器处理三元运算符时,它会尝试确定是否可以将两个操作数隐式转换为公共类型1,如果是,则使用该公共类型作为表达式的类型.
在上面的代码中,内部三元运算符:true? &d2 : p将尝试将表达式&d2的类型与类型匹配p,它会发现它可以执行一个简单的向上转换,并将该子表达式的返回类型设置为B*.请注意,因为条件是true,它将始终屈服&d2,即使它使用第三个参数来确定类型.
使用封闭表达式执行相同的操作,其中第二个参数是&d1(type D1*),第三个参数的类型是B*.同样,通过向上转换,转换是微不足道的D1*,整个表达式的类型是B*.
因为所有的转换都是由编译器隐式执行的,如果你改变了指针的类型,并打破了它们可以隐式转换的不变量,编译器会告诉你,解决了static_cast在三元组中间抛出一个问题的问题.运营商.
1标准规定了一组不同的转换,具体取决于参数的类型.在两个参数为指针的特定情况下(如此处所示),允许的转换是指针转换和限定转换.
[三元] 条件运算符要求其第二个和第三个操作数具有相同的类型。
b = boolean_expression ? new D1 : new D2;
Run Code Online (Sandbox Code Playgroud)
你有不同的类型D1*和D2*. 正如错误消息所示,您必须通过显式转换(即强制转换)确保正确的类型:
b = boolean_expression ? static_cast<B*>(new D1) : static_cast<B*>(new D2);
Run Code Online (Sandbox Code Playgroud)
该标准说编译器必须要求这样做(而不仅仅是进行隐式转换),所以这就是您的编译器所要求的。