Avi*_*ohn 4 c++ variables expression variable-assignment
这行不会编译:
Shape shape = (i % 2) ? Circle(5) : Rectangle(5, 5);
Run Code Online (Sandbox Code Playgroud)
(我知道它没用,因为表达式返回的内容将简化为简单Shape,这不是重点).
无法弄清楚为什么它不会编译.我正在创建一个Shape名为的变量shape(我认为此时会创建一个新Shape变量),然后我将此变量赋给表达式的结果.为什么不编译?
错误:
no match for ternary operator
Run Code Online (Sandbox Code Playgroud)
什么是真正奇怪的是,有完全相同的含义较长的代码并编译和运行按预期:
Shape shape;
if (i % 2)
shape = Rectangle(5, 5);
else
shape = Circle(5);
Run Code Online (Sandbox Code Playgroud)
条件运算符的详细转换规则相当复杂(如果您感兴趣,可以在此答案中找到标准的完整引用).缺点是,当与类类型的对象一起使用时,它将尝试转换其第二个操作数以匹配第三个操作数的类型,并将其第三个操作数与第二个类型相匹配,但它不会尝试将两者都转换为第三类类型.
由于Circle不可转换为Rectangle和Rectangle不可转换Circle,编译器会抱怨(好吧,除非这两种类型定义了一些奇怪的转换为指针,作用域枚举或算术类型,在这种情况下§5.16[expr.cond]/p5来了发挥).
另请注意,您的赋值将对对象进行切片,这可能不是一个好主意.
条件运算符的第二个和第三个操作数必须具有公共类型,可以使用std::common_type特征确定.有趣的是,从公共基类派生的两个类不具有该基类作为公共类型,因此指针或引用也不相关.进一步的思考很快就表明,这样的概念确实没有意义:两个类可以有任意数量的基类,并且通常无法选择唯一的首选基类.
如果要在条件运算符中使用派生类,则必须自己明确地转换类型.
代码的一个更现实和明智的例子是这样的:
Shape const & s = ask_user() ? static_cast<Shape const &>(show_me_a_circle())
: static_cast<Shape const &>(squares_all_the_way());
std::cout << "Your shape is " << s.get_colour() << ".\n";
Run Code Online (Sandbox Code Playgroud)