www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Type inference in array literals

reply klickverbot <see klickverbot.at> writes:
I was really surprised by the fact that the following code does not work 
(DMD 2.048 infers the type of the array literal to B[], not Object[]):

---
class A {}
class B {}

void main() {
    Object[] foo = [ new A, new B ];
}
---

Is this by design? If so, what are the reasons for not using the first 
common supertype of all the elements as type for the array literal?

This is quite irritating, since there apparently is no direct way of 
specifying the array literal save for casting the first element to 
Object (or whatever base class/interface you actually use in your code), 
which looks quite strange.
Aug 28 2010
next sibling parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
D uses the last element in the array literal to select the type. I think there
was a discussion on why a common type wasn't used, but don't remember the
conclusion. It would be nice if it used the item you are assigning to and check
they can convert to it.

klickverbot Wrote:

 I was really surprised by the fact that the following code does not work 
 (DMD 2.048 infers the type of the array literal to B[], not Object[]):
 
 ---
 class A {}
 class B {}
 
 void main() {
     Object[] foo = [ new A, new B ];
 }
Aug 28 2010
next sibling parent Max Samukha <spambox d-coding.com> writes:
On 08/28/2010 07:19 PM, Jesse Phillips wrote:
 D uses the last element in the array literal to select the type. I think there
was a discussion on why a common type wasn't used, but don't remember the
conclusion. It would be nice if it used the item you are assigning to and check
they can convert to it.
According to TDPL (page 40), common type should be used: "The element type of the array is determined by agreement among all elements of the array, which is computed by means of the conditional operator ? : (anticipating § 2.3.16)."
Aug 28 2010
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Jesse Phillips:

 D uses the last element in the array literal to select the type.
That's not true, this doesn't assert: import std.stdio: writeln; void main() { auto a = [1, 1.5, 2]; assert(is(typeof(a) == double[])); } I think it uses ?: on all elements, to infer the type. Bye, bearophile
Aug 28 2010
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Sat, Aug 28, 2010 at 18:19, Jesse Phillips
<jessekphillips+D gmail.com<jessekphillips%2BD gmail.com>
 wrote:
 D uses the last element in the array literal to select the type. I think
 there was a discussion on why a common type wasn't used, but don't remember
 the conclusion. It would be nice if it used the item you are assigning to
 and check they can convert to it.
No no, it has been changed months ago. It indeed computes the common type, for numeric types at least auto a = [1, 2u, 3.45678, 9]; // a is a double[] I think it does this with the ?: ternary operator. As for kickverbot question, I think it's a bug. You should see if it's already in bugzilla, or report it. std.traits.CommonType works, though: alias CommonType!(A,B) O; writeln(O.stringof); // "Object" and also the ?: operator: writeln(typeof(true ? new A() : new B()).stringof); // "Object" Philippe
Aug 28 2010
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
klickverbot:
 class A {}
 class B {}
 
 void main() {
     Object[] foo = [ new A, new B ];
 }
See also: http://d.puremagic.com/issues/show_bug.cgi?id=4030 Bye, bearophile
Aug 28 2010