我知道三元运算符有一些令人惊讶的限制,但我有点困惑,因为它无法为我编译:
void foo(bool b)
{
int* ptr = ((b) ? NULL : NULL);
}
显然,这是显示问题所需的最低限度。错误是:
[BCC32 Error] Unit11.cpp(20): E2034 Cannot convert 'int' to 'int *'
编译器是不到100%符合Embarcadero C ++ Builder 2010的,因此编译器错误绝非不可能......
注意:改变Parens以避免混淆我的意图。
注意2:我对自己如何首先得到这个结构感到有些困惑,所以这是我的借口:我在a = b? c : d
这样的行上得到了一些编译错误,其中b ,c和d都是复杂的表达。为了缩小范围,我将c
和d
替换为NULL
,以便检查b
是否是罪魁祸首。在这一点上,一切都在手推车里下地狱。
答案 0 :(得分:23)
NULL
是一个扩展为0
的宏(或一些值为0
的整数常量表达式,例如(1 - 1)
)。这不是“特别的”。
任何值为零的整型常量表达式都可用作空指针常量,这是允许int* ptr = 0;
的原因。但是,这里的表达式为b ? 0 : 0
;这不是一个整数常量表达式(b
不是常数);其类型为int
,不能隐式转换为int*
解决方法是明确指定您需要指针类型:
int* const null_int_ptr = 0;
int* ptr = b ? null_int_ptr : null_int_ptr;
这个例子有点人为:通常当一个人使用条件运算符时,至少有一个参数实际上是一个指针类型(例如b ? ptr : 0
);当其中一个操作数是指针类型时,0
被隐式转换为相同的指针类型,因此整个条件表达式的类型是指针类型,而不是int
。
唯一可以解决这个“问题”的情况是空指针常量用作条件运算符的第二个和第三个操作数,这很奇怪。
答案 1 :(得分:4)
您的问题是,您的系统NULL
被定义为0
,假定它是三元运算符上下文中的int。如果你static_cast
int*
的一个操作数,它应该自动提升另一个操作数。
但为什么首先使用这样的结构呢?
答案 2 :(得分:3)
NULL
可以定义为类型int
或long
,因此三元运算符具有相同的类型。没有隐式转换为指针类型,因此编译器会生成错误。
这里的问题是从常量整数表达式求值到零的隐式转换(臭名昭着的空指针常量)。
这里可能的解决方案是明确的演员:
int* ptr = b ? (int*) NULL : NULL;