www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - cannot initalize a struct for AA

reply Michelle Long <HappyDance321 gmail.com> writes:
AA[key] = {a,b,c};

fails.

T a = {a,b,c};
AA[key] = a;

passes.

The extra line is required simply to work, but there should be no 
difference semantically.
Dec 14 2018
next sibling parent reply Neia Neutuladh <neia ikeran.org> writes:
On Sat, 15 Dec 2018 02:22:51 +0000, Michelle Long wrote:
 AA[key] = {a,b,c};
 
 fails.
AA[key] is not a variable initialization. Struct initializer literals are only valid at variable initialization. I think a few people (at least one, which is to say, me) have looked at adding a way to make them work at arbitrary locations. One thing that makes that not so easy is that the syntax doesn't include the type, so you'd need a way to explicitly specify it. For example: --- struct Foo { int i; } struct Bar { int i; } struct HasProperty { void property(Foo foo) {} void property(Bar bar) {} } HasProperty hp; hp.property = {i: 10}; --- Which overload should that call? It's ambiguous. An alternative would be to add reorderable, default-value-able named parameters and make compiler-generated struct constructors use them. That's a much more general solution and is therefore more likely to land in the language.
Dec 14 2018
parent Jonathan Marler <johnnymarler gmail.com> writes:
On Saturday, 15 December 2018 at 02:33:27 UTC, Neia Neutuladh 
wrote:
 On Sat, 15 Dec 2018 02:22:51 +0000, Michelle Long wrote:
 [...]
AA[key] is not a variable initialization. Struct initializer literals are only valid at variable initialization. I think a few people (at least one, which is to say, me) have looked at adding a way to make them work at arbitrary locations. One thing that makes that not so easy is that the syntax doesn't include the type, so you'd need a way to explicitly specify it. For example: [...]
I have hopes that one day we'll have support for something like `Foo{i:10}`.
Dec 14 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, December 14, 2018 7:22:51 PM MST Michelle Long via Digitalmars-d 
wrote:
 AA[key] = {a,b,c};

 fails.

 T a = {a,b,c};
 AA[key] = a;

 passes.

 The extra line is required simply to work, but there should be no
 difference semantically.
There is a difference. In the case of T a = {a,b,c}; you're declaring a variable and explicitly initializing it. In the case of AA[key] = {a,b,c}; you're assigning a value to a function which is using it to initialize a value inside the AA. Yes, it's an overloaded function, but it's still not semantically the same as initializing a variable. If anything, it's more like an assignment than initialization, and basic assignment doesn't work with that syntax either. e.g. struct S { int x; int y; } void main() { S s; s = { 42, 19 }; } will fail to compile. That particular syntax _only_ works with direct initialization. For better or worse, D does do some special stuff with direct initialization that uses type inference that never gets used elsewhere (this particular struct initialization syntax being one such example), but for most code, the expression has to be known beforehand, so its type isn't inferred. This includes assignment and function calls where the target type is known. Now, there are folks who want to be able to do stuff like foo({42, 19}); and have that work, and IIRC, someone was working on a DIP to allow that sort of thing (which would presumably then include your use case), but as it stands, that does not work. Instead, you can just use the normal constructor syntax. e.g. struct S { int x; int y; } void main() { S s; s = S(42, 19); } will work just fine, and the AA case will work as well. And for better or worse, you don't even need to declare a constructor for a struct where you just want to have the variables initialized without doing anything else in the constructor. So, if you were using the {} syntax to avoid declaring a constructor, that's unnecessary (though I've found that it's better practice to just always declare a constructor and use it, because otherwise, you get fun bugs if/when the struct gets changed later by having members added, or if their order of declaration is changed). - Jonathan M Davis
Dec 14 2018
parent Jacob Carlborg <doob me.com> writes:
On 2018-12-15 03:40, Jonathan M Davis wrote:

 Now, there are folks who want to be able to do stuff like
 
 foo({42, 19});
 
 and have that work, and IIRC, someone was working on a DIP to allow that
 sort of thing (which would presumably then include your use case)
No, the DIP is to be able to use static initialization using the fields in arbitrary expressions, i.e. foo(S{ y: 19, x: 42 }); -- /Jacob Carlborg
Dec 16 2018