c++ 使用三元条件运算符时操作数类型不兼容

mzsu5hc0  于 6个月前  发布在  其他
关注(0)|答案(2)|浏览(84)

此代码:

bool contains = std::find(indexes.begin(), indexes.end(), i) != indexes.end();
CardAbility* cardAbility = contains ? new CardAbilityBurn(i) : new CardAbilityEmpty;

字符串
给了我以下错误:
操作数类型CardAbilityBurn和CardAbilityEmpty不兼容
如果我这样写代码:

if (contains)
{
    cardAbility = new CardAbilityBurn(i);
}
else
{
    cardAbility = new CardAbilityEmpty;
}


..
我需要注意(我想你可能需要这些信息),CardAbilityEmptyCardAbilityBurn都是从CardAbility派生出来的,所以可以说它们是兄弟。

m1m5dgzv

m1m5dgzv1#

C的类型系统从内到外确定表达式的类型[1]。这意味着条件表达式的类型在赋值给CardAbility*之前就已经确定了,编译器只能选择CardAbilityBurn*CardAbilityEmpty*
由于C
具有多重继承和一些更可能的转换路径,因为没有一个类型是另一个类型的超类,因此编译到此为止。
要成功编译,您需要提供缺少的部分:将一个或两个操作数强制转换为基类类型,以便条件表达式作为一个整体可以采用该类型。

auto* cardAbility = contains
    ? static_cast<CardAbility*>(new CardAbilityBurn(i))
    : static_cast<CardAbility*>(new CardAbilityEmpty  );

字符串
(Note auto的使用,因为你已经在右边的表达式中提供了目的地类型。)
然而,它 * 是 * 有点复杂,所以最终if-else结构更适合这种情况。
[1]但有一个例外:重载的函数名在转换(隐式或显式)为它们的一个版本之前没有确定的类型。

snvhrwxg

snvhrwxg2#

several cases described for Microsoft compilers,如何处理操作数类型。
如果两个操作数的类型相同,则结果为该类型。
如果两个操作数都是算术或枚举类型,则执行通常的算术转换(在算术转换中介绍)以将它们转换为公共类型。
如果两个操作数都是指针类型,或者一个是指针类型,另一个是计算结果为0的常量表达式,则执行指针转换以将它们转换为公共类型。
如果两个操作数都是引用类型,则执行引用转换以将它们转换为公共类型。
如果两个操作数都是void类型,则公共类型为void类型。
如果两个操作数属于同一用户定义类型,则公共类型就是该类型。
如果操作数有不同的类型,并且至少有一个操作数有用户定义的类型,则使用语言规则来确定公共类型。(参见下面的警告。)
还有一个警告:
如果第二个和第三个操作数的类型不相同,则调用C++标准中指定的复杂类型转换规则。这些转换可能导致意外行为,包括临时对象的构造和析构。因此,我们强烈建议您(1)避免使用用户定义类型作为条件运算符的操作数,或者(2)如果您确实使用用户定义类型,然后将每个操作数显式转换为公共类型。
也许,这就是苹果在LLVM中停用这种隐式转换的原因。
所以,if/else似乎更适合你的情况。

相关问题