铸造指针和三元?:操作人员我重新发明轮子了吗
Casting pointers and the ternary ?: operator. Have I reinvented the wheel?
此代码的最后一行无法使用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;
}
g++(Ubuntu 4.3.3-5ubuntu4)4.3.3
更新根据@Konrad的回答
implicit_cast
更改为up_cast
一个真正聪明的编译器不会有任何困难,因为两者都可以安全地广播到
B*
无关。标准要求这种行为。一个真正聪明的编译器的行为正如所观察到的那样。
使用自定义强制转换实际上很好(而且您不愿意使用显式强制转换的情况也很好)。然而,我会使用一个不同的名称:upcast
——因为这是在这里发生的:在继承层次结构中向上转换。
[三元]条件运算符要求其第二个和第三个操作数具有相同的类型。
b = boolean_expression ? new D1 : new D2;
您有不同的类型D1*
和D2*
。正如错误消息所示,您必须通过显式转换(即强制转换)确保正确的类型:
b = boolean_expression ? static_cast<B*>(new D1) : static_cast<B*>(new D2);
标准规定编译器必须这样做(而不仅仅是进行隐式转换),所以这就是编译器的要求。
我本来不打算回答,但在发布评论后,我想,这是什么。。。这是一种与其他方法一样的方法:
int main() {
bool condition = true;
D1 d1;
D2 d2;
B * p = condition ? &d1 : (true? &d2 : p );
}
基本上滥用三元运算符来提取适当的类型。当编译器处理三元运算符时,它试图确定两个操作数是否可以隐式地转换为公共类型1,如果是,它将使用该公共类型作为表达式的类型。
在上面的代码中,内部三元运算符:true? &d2 : p
将尝试将表达式&d2
的类型与p
的类型匹配,它会发现有一个简单的上转换可以执行,并将该子表达式的返回类型设置为B*
。请注意,因为条件是true
,所以它将始终生成&d2
,即使它使用第三个参数来确定类型也是如此。
对封闭表达式执行相同的操作,其中第二个参数是&d1
(类型为D1*
),第三个参数的类型是B*
。同样,通过向上投射D1*
,转换是微不足道的,并且整个表达式的类型是B*
。
由于所有的转换都是由编译器隐式执行的,如果您更改指针的类型,并打破它们可以隐式转换的不变,编译器会告诉您,解决了在三元运算符中间抛出static_cast
的问题。
1标准规定了一组不同的转换,具体取决于参数的类型。在两个参数是指针的特殊情况下(如这里的情况),允许的转换是指针转换和限定转换
我刚刚遇到了这个问题,丢失了铸造,用长的方法进行铸造是最干净的IMO
B * d1 = new D1();
B * d2 = new D2();
B * b = boolean_expression ? d1 : d2;
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 堆栈粉碎 在我在代码中添加新变量以及一些操作后C++检测到
- 宏如何在Tensorflow中添加新的操作时"REGISTER_OP("ZeroOut")
- 在c++中从包含新操作的python中创建的pb图创建图
- 是新的(&*p)双倍;一个无操作。因此,uninitialized_default_construct是否也变得无操作?
- 当我尝试在 tensorflow 中添加一个新操作时如何 #include "include/libxsmm.h"?
- 在张量流中创建新操作时指定形状句柄的形状(输出张量的秩问题)
- 在张量流中导入图形时使用新的操作
- 访问新创建的操作时出现问题
- 将字符数复制到新字符串位置的字符串操作,例如 S[0]
- 无法获得新的 tf。在 Tensorflow 中的 Python shell 中工作的操作
- 在新的 c++11 项目中,我是否应该默认删除任何操作
- C++预处理器+检测对象类型和新操作
- 使用新操作器创建多个对象
- 为线程设置新优先级时不允许操作
- C++使用新操作制作 int 数组
- 如何制作一个在每次输出操作后插入新行的流
- Linux c++新操作慢得令人难以置信
- 铸造指针和三元?:操作人员我重新发明轮子了吗
- C++提供"切片"操作的字符串类(不创建新的字符串副本)