我知道三元运营商有一些令人惊讶的限制,但是我有些困惑,因为这对我来说没有编译:

void foo(bool b)
{
    int* ptr =  ((b) ? NULL : NULL);
}

显然,这是显示问题所需的最低限度。错误是:

[BCC32 Error] Unit11.cpp(20): E2034 Cannot convert 'int' to 'int *'

编译器是比100%的不符合组合的Embarcadero C ++构建器2010,因此编译器错误远非不可能...

注意:帕伦斯(Parens)进行了修改,以避免对我的意图感到困惑。

Note2:我对我如何到达这个结构有些困惑 a = b? c : d, ,其中b,c和d都是复杂的表达式。为了缩小它,我替换了 cdNULL为了检查是否是否 b 是罪魁祸首。在这一点上,一切都戴着手套。

有帮助吗?

解决方案

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.

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

其他提示

您的问题是在您的系统上 NULL 被定义为 0 在三元操作员的上下文中,它被认为是INT。如果你 static_cast 操作数之一 int* 它应该自动推出另一个。

但是,为什么首先使用这样的构造呢?

NULL 可以定义为具有类型 int 甚至 long, ,因此三元运算符具有相同的类型。没有隐式转换到指针类型,因此编译器会生成错误。这里的陷阱是,从恒定整数表达式评估到零(臭名昭著的无效指针常数)存在隐式转换。

这里可能的解决方案是一个明确的演员:

int* ptr =  b ? (int*) NULL : NULL;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top