三元运算符的指针转换问题

Rod*_*ddy 20 c++ conditional-operator null-pointer c++builder-2010 constant-expression

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

void foo(bool b)
{
    int* ptr =  ((b) ? NULL : NULL);
}
Run Code Online (Sandbox Code Playgroud)

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

[BCC32 Error] Unit11.cpp(20): E2034 Cannot convert 'int' to 'int *'
Run Code Online (Sandbox Code Playgroud)

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

注意:修改Parens以避免混淆我的意图.

注2:我对自己如何首先得到这个结构感到有些困惑,所以这是我的借口:我在一行上得到了一些编译错误a = b? c : d,其中b,c和d都是复杂的表达式.为了缩小范围,我用s 代替c,以检查是否是罪魁祸首.在这一点上,一切都在手推车里下地狱.dNULLb

Jam*_*lis 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;
Run Code Online (Sandbox Code Playgroud)

但是这个例子有点人为:通常当一个人使用条件运算符时,至少有一个参数实际上是一个指针类型(例如b ? ptr : 0); 当其中一个操作数是指针类型时,它0被隐式转换为相同的指针类型,因此整个条件表达式的类型是指针类型,而不是int.

你可以遇到这个"问题"的唯一情况是空指针常量被用作条件运算符的第二个和第三个操作数,这是相当奇怪的.

  • 那么来自C++ 11的`nullptr`怎么样?`int*ptr = b?nullptr:nullptr;`工作? (7认同)
  • 是的,`nullptr`会编译得很好,因为结果类型将是`nullptr_t`.这种事情是为什么`nullptr`被添加到语言中. (4认同)