On Mon, 05 Jan 2009 18:58:54 +0300, leo <l...@clw-online.de> wrote:
Hi,
while I was reading the language specification I stumbled across the
following problem:
Tuple!(int, int) x = Tuple!(1, 2); // doesn't compile
Tuple!(int, int) y = (1, 2); // leads to y being (2, 2)
How can I initialize a tuple by providing another tuple?
I know it's still possible to assign each element of the tuple
separately, I'm just wondering what sense it makes
to define an expression (1, 2) to be 2 of type int rather than (1, 2)
of type (int, int).
Is there any case in which this would provide an advantage?
Leo
You have two mistakes, one for each lines of code :)
But you were close to right solutions.
1) Tuple!(int, int) x = Tuple!(1, 2); // doesn't compile
Of course it doesn't, don't confuse type definition with a constructor
call. In this case, "Tuple!(int, int)" is a type, and so is "Tuple!(1,
2)" (although template parameters are invalid; types are expected, not
expressions). We could rewrite this line as follows:
But template parameters also allow for expressions, so that tuples can
also
be expression tuples.
A x = B; // where A and B are type aliases
What you need here is a constructor call:
A x = A(1, 2);
or
Tuple!(int,int) x = Tuple!(int,int)(1, 2);
This wouldn't work since Tuple!(int, int) has no opCall
2) Tuple!(int, int) y = (1, 2); // leads to y being (2, 2)
Here is another quest - what does the following lines do?
int x = 1, 2;
int y = (1, 2);
The above doesn't compile, because it's actually a declaration of a
variable
"int x = 1;" and another syntactically wrong one "int 2;". The comma is
associated with the DeclarationStatement, not the expression.
In the second line the parentheses tell the compiler to treat "1, 2" as
an
expression.
The first line, yes (I didn't say it should compile). The second line does, in
fact, assigns 2 to y (instead of 1). This is the same as your example but with
int instead of Tuple(int,int).
They are absolutely the same and both initialize variables to 2, that's
the way comma expression works (it evaluates all the expression and
returns result of last expression).
Same here:
"Tuple!(int, int) y = (1, 2);" == "Tuple!(int, int) y = 2;"
If you want per-member struct initialization, you should use curly
braces instead:
Tuple!(int, int) y = {1, 2};
Curly braces won't work either, because Tuple!(int, int) can not be
initialized per-member. I tried also
Tuple!(int, int) x;
x = (1, 2); // here I get an error message "forward reference to type
(int,
int)
x = {1, 2}; // this produces a lot of "found 'EOF' instead of statement"
errors
I compiled with dmd v1.038, v2.014 and v2.022
It's not like I would ever need to initialize a tuple like that, I'm just
curious
anyway, thanks for the answer
Leo
Both work for me (dmd 2.012):
import std.typecons;
void main()
{
Tuple!(int, int) x = Tuple!(int, int)(1, 2);
Tuple!(int, int) y = {1, 2};
}