digitalmars.D.learn - Arrays of variants, C++ vs D
- JN (36/36) Jun 17 2021 This C++ code compiles:
- H. S. Teoh (10/18) Jun 17 2021 Because D does not support implicit construction. The array literal is
- Steven Schveighoffer (15/29) Jun 17 2021 Implicit construction is supported:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (24/31) Jun 17 2021 That's so unlike the rest of the language that I consider it to be a
- Steven Schveighoffer (25/30) Jun 17 2021 The difference might be that construction has only one set of overloads
This C++ code compiles: ```cpp #include <variant> #include <string> #include <map> int main() { using Foo = std::variant<int, std::string>; std::map<int, Foo> foos = {{0, "abc"}, {1, 5}}; } This code doesn't: ```d import std.variant; void main() { alias Foo = Algebraic!(int, string); Foo[int] foos = [ 0: "abc", 1: 5 ]; } ``` but this does: ```d import std.variant; void main() { alias Foo = Algebraic!(int, string); Foo[int] foos = [ 0: Foo("abc"), 1: Foo(5) ]; } ``` Why does D need the explicit declarations whereas C++ can infer it?
Jun 17 2021
On Thu, Jun 17, 2021 at 07:44:31PM +0000, JN via Digitalmars-d-learn wrote: [...]Foo[int] foos = [ 0: Foo("abc"), 1: Foo(5) ]; } ``` Why does D need the explicit declarations whereas C++ can infer it?Because D does not support implicit construction. The array literal is parsed as-is, meaning string[int] is inferred rather than Foo[int]. So the initialization fails because of a type mismatch. Implicit construction has been asked for many times, but Walter has been adamant about not allowing implicit construction in D. T -- Music critic: "That's an imitation fugue!"
Jun 17 2021
On 6/17/21 4:15 PM, H. S. Teoh wrote:On Thu, Jun 17, 2021 at 07:44:31PM +0000, JN via Digitalmars-d-learn wrote: [...]Implicit construction is supported: struct Foo { int x; this(int y) { x = y; } } Foo f = 5; // ok implicit construction What is happening here though is that the construction is being done as an AA literal. This works for *some* types, but not all. e.g.: Foo[int] f = [5 : 5]; // error double[int] f = [5 : 5]; // ok It really should work IMO. -SteveFoo[int] foos = [ 0: Foo("abc"), 1: Foo(5) ]; } ``` Why does D need the explicit declarations whereas C++ can infer it?Because D does not support implicit construction. The array literal is parsed as-is, meaning string[int] is inferred rather than Foo[int]. So the initialization fails because of a type mismatch.
Jun 17 2021
On 6/17/21 1:46 PM, Steven Schveighoffer wrote:Implicit construction is supported: struct Foo { int x; this(int y) { x = y; } } Foo f = 5; // ok implicit constructionThat's so unlike the rest of the language that I consider it to be a bug. :) Really, why? What if the expression is more complicated: int i() { return 1; } Foo f = i(); OK, that works as well. Wow! But the following doesn't and is what I think Walter has been trying to prevent: struct Foo { int x; this(int y) { x = y; } } void foo(Foo) { } void main() { foo(42); // COMPILATION ERROR } What's the difference? In both cases an int is being converted to a Foo. I think the "working" case is against the design of D. Likely there is a subtlety that I am missing... Ali
Jun 17 2021
On 6/17/21 5:01 PM, Ali Çehreli wrote:What's the difference? In both cases an int is being converted to a Foo. I think the "working" case is against the design of D. Likely there is a subtlety that I am missing...The difference might be that construction has only one set of overloads -- the constructor of the item being created. With your example, there's the set of overloads to create a Foo and the set of overloads to call foo. Imagine this: struct Foo { int x; this(int y) { x = y; } } struct Bar { int x; this(int y) { x = y; } } void foo(Foo f){} void foo(Bar b){} void main() { foo(42); // which one? } But I don't know. I know that there are all kinds of subtle problems with C++ implicit conversions, and D is right to avoid all that. But this might be one case where the decision tree is easy. -Steve
Jun 17 2021