digitalmars.D.learn - Confused by struct constructors
- Simen kjaeraas (40/40) Jan 23 2010 In attempting to create a function to initialize any array of structs in...
- bearophile (4/8) Jan 23 2010 That syntax is not useful, if you have few more structs or fields you ar...
- Philippe Sigaud (23/31) Jan 23 2010 U is a type . U[0..n] is also a type. You should write:
- Simen kjaeraas (32/48) Jan 23 2010 =
- Philippe Sigaud (5/6) Jan 23 2010 Nice looking character. Indian, hebrew?
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
Jan 23 2010
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
Jan 23 2010
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
Jan 23 2010
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=Thank you! Darn, I should have been able to see that.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:Maybe you could also use S.tupleof.length to get the number of fields =in =SYeah, 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
Jan 23 2010
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
Jan 23 2010