www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - "Common type" of the ternary operator expressions

reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
"Conditional Expressions" on this page covers the ternary operator as well:

   http://digitalmars.com/d/2.0/expression.html#ConditionalExpression

It says "the second and third expressions are implicitly converted to a 
common type which becomes the result type of the conditional expression."

How "common" should the "common type" be? Wouldn't you expect the 
following ternary operator's result be I, instead of Object?

interface I {}
class A : I {}
class B : I {}

void foo(I) {}

void main()
{
     bool some_condition;
     foo(some_condition ? new A : new B);  // <-- compiler error
}

Compiler error:

Error: function deneme.foo (I _param_0) is not callable using argument 
types (Object)
Error: cannot implicitly convert expression (some_condition ? new A : 
new B) of type object.Object to deneme.I

Ali
May 24 2010
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
Ali Çehreli wrote:
 "Conditional Expressions" on this page covers the ternary operator as well:
 
   http://digitalmars.com/d/2.0/expression.html#ConditionalExpression
 
 It says "the second and third expressions are implicitly converted to a 
 common type which becomes the result type of the conditional expression."
 
 How "common" should the "common type" be? Wouldn't you expect the 
 following ternary operator's result be I, instead of Object?
 
 interface I {}
 class A : I {}

My expectation is that the hierarchy of A should look like this: Object | I | A For me, Object should always be at the top. I know that interfaces can not inherit from classes; but as now the interfaces may have implementations, perhaps it's time to make Object an interface, as opposed to a class?
 class B : I {}
 
 void foo(I) {}
 
 void main()
 {
     bool some_condition;
     foo(some_condition ? new A : new B);  // <-- compiler error
 }
 
 Compiler error:
 
 Error: function deneme.foo (I _param_0) is not callable using argument 
 types (Object)
 Error: cannot implicitly convert expression (some_condition ? new A : 
 new B) of type object.Object to deneme.I

Thank you, Ali
May 24 2010
parent reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
On 05/24/2010 06:36 PM, Ali Çehreli wrote:
 Ali Çehreli wrote:
 "Conditional Expressions" on this page covers the ternary operator as
 well:

 http://digitalmars.com/d/2.0/expression.html#ConditionalExpression

 It says "the second and third expressions are implicitly converted to
 a common type which becomes the result type of the conditional
 expression."

 How "common" should the "common type" be? Wouldn't you expect the
 following ternary operator's result be I, instead of Object?

 interface I {}
 class A : I {}

My expectation is that the hierarchy of A should look like this: Object | I | A

interfaces are not objects, so crush your expectations. Question: what should happen with class A : I, J {} class B : I, J {} ?
May 24 2010
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
Ellery Newcomer wrote:
 On 05/24/2010 06:36 PM, Ali Çehreli wrote:
 Ali Çehreli wrote:
 "Conditional Expressions" on this page covers the ternary operator as
 well:

 http://digitalmars.com/d/2.0/expression.html#ConditionalExpression

 It says "the second and third expressions are implicitly converted to
 a common type which becomes the result type of the conditional
 expression."

 How "common" should the "common type" be? Wouldn't you expect the
 following ternary operator's result be I, instead of Object?

 interface I {}
 class A : I {}

My expectation is that the hierarchy of A should look like this: Object | I | A

interfaces are not objects, so crush your expectations.

I guess this is how it actually is: I Object \ / A
 Question: what should happen with

 class A : I, J {}
 class B : I, J {}

Good point. I think the error message threw me off: Error: cannot implicitly convert expression (some_condition ? new A : new B) of type object.Object to deneme.I The compiler apparently does go up in the hierarchy, but it favors the Object branch. (C++ does not try to find a common ancestor; stays with the types A and B.) Ali
May 24 2010