Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 投射指针和三元?:运算符。我重新发明了轮子吗?_C++_Casting_Ternary Operator - Fatal编程技术网

C++ 投射指针和三元?:运算符。我重新发明了轮子吗?

C++ 投射指针和三元?:运算符。我重新发明了轮子吗?,c++,casting,ternary-operator,C++,Casting,Ternary Operator,此代码的最后一行无法使用casting和triangal进行编译。cpp:15:错误:不同指针类型“D1*”和“D2*”之间的条件表达式缺少cast 一个真正聪明的编译器不会有什么困难,因为两者都可以安全地转换为B*(基类)。我不愿意使用静态强制转换和动态强制转换等等-我担心有一天我会混淆这些类,并得到未定义的行为。这就是我创建up_cast模板的原因。此模板在允许的转换中执行最低限度的操作。有没有更简单的方法?还有其他的解决办法,但我忍不住想,还有更简单、更安全的方法可以使用吗 struct

此代码的最后一行无法使用
casting和triangal进行编译。cpp:15:错误:不同指针类型“D1*”和“D2*”之间的条件表达式缺少cast

一个真正聪明的编译器不会有什么困难,因为两者都可以安全地转换为
B*
(基类)。我不愿意使用静态强制转换和动态强制转换等等-我担心有一天我会混淆这些类,并得到未定义的行为。这就是我创建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;
}
结构B{}; 结构D1:公共B{}; 结构D2:公共B{}; 模板 T向上倾斜(V x){ 返回x; } int main(){ 布尔表达式=真; B*B; b=新的D1; b=新的D2; b=布尔表达式?向上转换(新D1):向上转换(新D2); b=布尔_表达式?新D1:新D2; } g++(Ubuntu 4.3.3-5ubuntu4)4.3.3

更新根据@Konrad的回答,将名称从
隐式转换
更改为
向上转换

一个真正聪明的编译器不会有什么困难,因为两者都可以安全地转换到
B*

无关紧要。标准规定了这种行为。真正智能的编译器的行为与观察到的一样


使用自定义强制转换实际上是很好的(而且您不愿意使用显式强制转换的情况也很好)。但是,我会使用一个不同的名称:
upcast
——因为这是在这里发生的:继承层次结构中向上的强制转换。

三元]条件运算符要求其第二个和第三个操作数具有相同的类型

b = boolean_expression ? new D1 : new D2;
您有不同的类型
D1*
D2*
。如错误消息所示,您必须通过显式转换(即强制转换)确保正确的类型:

b=boolean\u表达式?静态演员阵容(新D1):静态演员阵容(新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
(type
d1*
),第三个参数的类型是
B*
。同样,通过向上转换
D1*
,转换非常简单,整个表达式的类型是
B*

因为所有的转换都是由编译器隐式执行的,如果你改变指针的类型,并且打破它们可以隐式转换的不变量,编译器会告诉你,解决在三元运算符的中间抛出一个<代码> SistaCysCase<代码>的问题。


1根据参数的类型,标准规定了一组不同的转换。在两个参数都是指针的特殊情况下(这里就是这种情况),允许的转换是指针转换和限定转换。

我刚刚遇到了这个问题,丢失了类型转换,然后进行了很长一段时间的转换

B * d1 = new D1();
B * d2 = new D2();
B * b = boolean_expression ? d1 : d2;

我想他知道这一点,只是在征求对他的
implicit_cast
模板的意见…@David:如果是真的,他就离题了,应该去codereview.)“隐性演员”这句话毫无意义。强制转换是一种显式转换。对于偶数weider方法:
b=boolean\u表达式?新D1:(真?新D2:(B*)0)我相信你的演员阵容在功能上与C风格的演员阵容完全相同。@Tomalak,我从“'static_cast'中得到了隐式这个词,它可以执行任何可以隐式执行的演员阵容,也可以执行反向演员阵容(即使这是不允许隐式执行的)。”(我强调)@Aaron McDaid:如果你要执行该演员阵容,我建议您显式地创建指针,这样如果您在非指针上尝试它(而不是潜在地创建副本),它将失败。考虑<代码> D1 D1;上石膏(d1)看起来很合理,但不会达到您可能期望的效果:
模板T*up_cast(U*p){return p;}
应该可以做到这一点。我很好奇为什么编译器会被强制投诉。虽然我承认在某些情况下,编译器可能会变得非常复杂;对于多重继承,这将是许多有效的“最小公分母”类。@Aaron:那么,编译器应该执行隐式转换到什么类型?我想你的意思是“如果一个操作数可以转换为与另一个操作数的类型相匹配”。当您说“隐式转换为公共类型”时,我感到很惊讶,因为我发现这令人困惑,并且它暗示了
条件&d1:&d2
应该是现成的+“一个漂亮的把戏。”@Aaron:情况不同。在David的例子中,只有一个参数转换为另一个参数的类型。在您的情况下,需要对所有基类进行彻底搜索。复杂性(和诡计)绝对不同。@Aaron,@Matthieu:标准
B * d1 = new D1();
B * d2 = new D2();
B * b = boolean_expression ? d1 : d2;