愚蠢的条件表达式?

来源:互联网 发布:淘宝小米官方旗舰店 编辑:程序博客网 时间:2024/04/28 06:26

愚蠢的条件表达式

首先看一段代码:

   1: class B {};
   2: class D1 : public B {};
   3: class D2 : public B {};
   4: void main()
   5: {
   6:     D1* pD1;
   7:     D2* pD2;
   8:     B* pB = true ? pD1 : pD2;
   9: }

上面代码第八行能通过编译吗?根据直观理解,它“等价”于

   1: if (true)
   2:     pB = pD1;
   3: else
   4:     pB = pD2;

如果编译不过,这种编译器绝不能要。可编译结果还真的是*失败*。第一次与这种问题亲密接触时,你会不会先骂一句‘愚蠢的条件表达式’呢!

条件表达式类型

骂舒坦之后,顺便找找茬,分析一下编译失败原因。表达式都有类型,遇到不能确定类型的表达式,编译就会失败。条件表达式是表达式(废话)。确定条件表达式类型的规则冗长且复杂,C++标准有一整页来描述。但是对非内置类型,其核心规则比较简单。设 XY 为第二个和第三个操作数所属的类型,

  • 如果 XY 的类型相同,则此类型为该条件表达式的类型。
  • 否则,如果存在从 XY 的隐式转换,但不存在从 YX 的隐式转换,则 Y 为条件表达式的类型。
  • 否则,如果存在从 YX 的隐式转换,但不存在从 XY 的隐式转换,则 X 为条件表达式的类型。
  • 否则,无法确定条件表达式的类型,且发生编译时错误。

根据上述规则,true? pD1 : pD2 的类型是无法确定的,所以编译时错误在所难免。

为什么要编译时确定表达式类型

既然是找茬,那就打破沙锅问到底。我知识浅薄,无法彻底弄明白。只是找到一些蛛丝马迹。

  • C++是强类型静态语言,编译期确定表达式类型有助于编写类型安全代码。
  • 泛型编程早已深入人心,而泛型编程中常常需要知道表达式的类型。C++0x甚至专门引入了decltype关键字来取得表达式的类型。

为什么不对赋值运算做特殊处理

第八行代码这种情况,为什么不对条件表达式类型做特殊处理,使得上述“等价”真的等价。似乎挺合理。嗯,那是你认为。特痛恨PD弄那么多特殊情况,把设计弄得乱七八糟,把Dev搞得死去活来。尽管这些特例看上去有一定道理,如本例。