|
Archives
D Programming
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.ide
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger
D.gnu
D
C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows
digitalmars.empire
digitalmars.DMDScript
electronics
|
digitalmars.D.learn - Confused by struct constructors
In attempting to create a function to initialize any array of structs in a
simple manner, I created this code:
void fillArr( uint n, T, U... )( ref T[] arr, U args ) {
arr[0] = T( U[0..n] );
static if ( U.length > n ) {
fillArr!( n )( arr[ 1..$ ], args[ n..$ ] );
}
}
T[] initArray( T, uint n = U.length, U... )( U args ) if ( n > 0 ) {
static if (
// ( __traits( compiles, T( args[ 0..n ] ) ) ) && // Same as below.
Added for completeness.
( is( typeof( T( args[ 0..n ] ) ) ) ) && // If we can instantiate a
struct with this
( U.length % n == 0 ) // and it matches the
number of arguments,
) {
T[] result = new T[ U.length / n ]; // Create an array
fillArr!( n )( result, args ); // and fill it.
return result;
} else {
return initArray!( T, n-1, U )( args ); // Didn't work. Try
another parameter count.
}
}
However, upon testing it with this code:
struct S {
int n;
string s;
}
auto s = initArray!( S )( 1, "a", 2, "b", 3, "c" );
I get this error:
foo.d(34): Error: cannot implicitly convert expression ((int _param_1,
string _param_2)) of type (int _param_1, string _param_2) to int
The problem is apparently on this line:
arr[0] = T( U[0..n] );
Though I am confuzzled as to why it does not work ( it works in initArray,
line 2 ). Any ideas?
--
Simen
Simen kjaeraas:
In attempting to create a function to initialize any array of structs in a
simple manner,
...
auto s = initArray!( S )( 1, "a", 2, "b", 3, "c" );
That syntax is not useful, if you have few more structs or fields you are lost
in the soup of commas and items..
Bye,
bearophile
--00032555b2ce963e93047dd7ff7f
Content-Type: text/plain; charset=ISO-8859-1
On Sat, Jan 23, 2010 at 14:44, Simen kjaeraas <simen.kjaras gmail.com>wrote:
In attempting to create a function to initialize any array of structs in a
simple manner, I created this code:
void fillArr( uint n, T, U... )( ref T[] arr, U args ) {
arr[0] = T( U[0..n] );
static if ( U.length > n ) {
fillArr!( n )( arr[ 1..$ ], args[ n..$ ] );
}
}
U is a type . U[0..n] is also a type. You should write:
arr[0] = T(args[0..n]);
Maybe you could also use S.tupleof.length to get the number of fields in S
(or maybe there is a __traits which gives this) and avoid the recursion in
initArray:
void fillArr( T, U... )( ref T[] arr, U args ) {
arr[0] = T(args[0..T.tupleof.length]) ;
static if ( U.length > T.tupleof.length ) {
fillArr( arr[ 1..$ ], args[ T.tupleof.length..$ ] );
}
}
T[] initArray( T, U... )( U args )
if ( U.length > 0
&& (is(typeof( T( args[ 0..T.tupleof.length ] ) ) ) )
&& ( U.length % T.tupleof.length == 0 ))
{
T[] result = new T[ U.length / T.tupleof.length ]; // Create an
array
fillArr( result, args ); // and fill it.
return result;
}
Philippe
--00032555b2ce963e93047dd7ff7f
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<br><br><div class=3D"gmail_quote">On Sat, Jan 23, 2010 at 14:44, Simen kja=
eraas <span dir=3D"ltr"><<a href=3D"mailto:simen.kjaras gmail.com">simen=
.kjaras gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote=
" style=3D"border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0=
.8ex; padding-left: 1ex;">
In attempting to create a function to initialize any array of structs in a =
simple manner, I created this code:<br>
<br>
void fillArr( uint n, T, U... )( ref T[] arr, U args ) {<br>
=A0arr[0] =3D T( U[0..n] );<br>
=A0static if ( U.length > n ) {<br>
=A0 =A0fillArr!( n )( arr[ 1..$ ], args[ n..$ ] );<br>
=A0}<br>
}<br></blockquote><div><br>U is a type . U[0..n] is also a type. You should=
write:<br><br>arr[0]=A0 =3D T(args[0..n]);<br><br><br>Maybe you could also=
use S.tupleof.length to get the number of fields in S (or maybe there is a=
__traits which gives this) and avoid the recursion in initArray:<br>
<br><br>void fillArr( T, U... )( ref T[] arr, U args ) {<br>=A0arr[0] =3D=
=A0 T(args[0..T.tupleof.length]) ;<br>=A0static if ( U.length > T.tupleo=
f.length ) {<br>=A0=A0 fillArr( arr[ 1..$ ], args[ T.tupleof.length..$ ] );=
<br>=A0}<br>
}<br><br>T[] initArray( T, U... )( U args )<br>=A0=A0=A0 if ( U.length >=
0<br>=A0=A0=A0 && (is(typeof( T( args[ 0..T.tupleof.length ] ) ) )=
)<br>=A0=A0=A0 && ( U.length % T.tupleof.length =3D=3D 0 ))<br>{<b=
r>=A0=A0 T[] result =3D new T[ U.length / T.tupleof.length ];=A0=A0=A0=A0=
=A0=A0=A0=A0 // Create an array<br>
=A0=A0 fillArr( result, args );=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 // a=
nd fill it.<br>=A0=A0 return result;<br>}<br><br><font color=3D"#888888">
</font></div></div>Philippe<br><br>
--00032555b2ce963e93047dd7ff7f--
On Sat, 23 Jan 2010 18:09:26 +0100, Philippe Sigaud =
<philippe.sigaud gmail.com> wrote:
On Sat, Jan 23, 2010 at 14:44, Simen kjaeraas =
<simen.kjaras gmail.com>wrote:
In attempting to create a function to initialize any array of structs=
in a
simple manner, I created this code:
void fillArr( uint n, T, U... )( ref T[] arr, U args ) {
arr[0] =3D T( U[0..n] );
static if ( U.length > n ) {
fillArr!( n )( arr[ 1..$ ], args[ n..$ ] );
}
}
U is a type . U[0..n] is also a type. You should write:
Thank you! Darn, I should have been able to see that.
Maybe you could also use S.tupleof.length to get the number of fields =
S
Yeah, I could. However, S might use a different constructor, taking a
different number of arguments.
As for bearophile's concerns:
struct simpleTuple( T... ) {
T payload;
}
simpleTuple!( T ) =E0=BA=95( T... )( T args ) {
return simpleTuple!( args );
}
T[] initArray( T, U... )( U args ) if ( is( typeof( T( args[0].tupleo=
f ) =
) ) && allSame!( U ) ) {
T[] result =3D new T[ U.length ];
foreach ( i, arg; args ) {
result[ i ] =3D T( arg.tupleof );
}
return result;
}
struct S {
int n;
string s;
}
auto s =3D initArray!( S )( =E0=BA=95( 1, "a" ), =E0=BA=95( 2, "b" ),=
=E0=BA=95( 3, "c" ) );
If =E0=BA=95 is too hard to type, choose another short name.
-- =
Simen
--0015174ff13cf96a4c047de42b7c
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
auto s =3D initArray!( S )( =E0=BA=95( 1, "a" ), =E0=BA=95( 2, "b" ), =E0=
=BA=95( 3, "c" ) );
If =E0=BA=95 is too hard to type, choose another short name.
Nice looking character. Indian, hebrew?
When I want an almost non-visible char, I tend tu use _, just _.
Philippe
--0015174ff13cf96a4c047de42b7c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=C2=A0auto s =3D initArray!( S )( =E0=BA=95( 1, "a" ), =E0=BA=95(=
2, "b" ), =E0=BA=95( 3, "c" ) );<br><div class=3D"gmai=
l_quote"><blockquote class=3D"gmail_quote" style=3D"border-left: 1px solid =
rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
If =E0=BA=95 is too hard to type, choose another short name.<br></blockquot=
e><div><br>Nice looking character. Indian, hebrew?<br><br>When I want an al=
most non-visible char, I tend tu use _, just _.<br><br>Philippe<br><br><br>=
=C2=A0<br>
</div></div>
--0015174ff13cf96a4c047de42b7c--
|
|