20

我知道三元运算符有一些令人惊讶的限制,但我有点困惑,这无法为我编译:

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,因此编译器错误远非不可能......

注意:修改括号以避免混淆我的意图。

注意 2:我对自己是如何得出这个结构感到有些困惑,所以这是我的借口:我在类似 的行上遇到了一些编译错误a = b? c : d,其中 b、c 和 d 都是复杂的表达式. 为了缩小范围,我将candd替换为NULLs 以检查是否b是罪魁祸首。在这一点上,一切都在手推车中陷入了困境。

4

3 回答 3

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.

唯一可能遇到此“问题”的情况是空指针常量同时用作条件运算符的第二个和第三个操作数,这很奇怪。

于 2011-07-25T16:59:33.203 回答
4

您的问题是,在您的系统NULL上被定义为0在三元运算符的上下文中假定为 int 。如果您static_cast的其中一个操作数int*应该自动提升另一个操作数。

但是为什么首先要使用这样的结构呢?

于 2011-07-25T17:00:32.610 回答
3

NULL可以定义为具有 typeint或 even long,因此三元运算符具有相同的类型。没有对指针类型的隐式转换,因此编译器会产生错误。这里的问题是存在从常量整数表达式计算为零的隐式转换(臭名昭著的空指针常量)。

这里可能的解决方案是显式转换:

int* ptr =  b ? (int*) NULL : NULL;
于 2011-07-25T17:03:38.727 回答