Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
January 23, 2010 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
|
January 23, 2010 Re: Confused by struct constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | 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
|
January 23, 2010 Re: Confused by struct constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas Attachments:
| 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
|
January 24, 2010 Re: Confused by struct constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | 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] = 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 in 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 ) ຕ( T... )( T args ) { return simpleTuple!( args ); } T[] initArray( T, U... )( U args ) if ( is( typeof( T( args[0].tupleof ) ) ) && allSame!( U ) ) { T[] result = new T[ U.length ]; foreach ( i, arg; args ) { result[ i ] = T( arg.tupleof ); } return result; } struct S { int n; string s; } auto s = initArray!( S )( ຕ( 1, "a" ), ຕ( 2, "b" ), ຕ( 3, "c" ) ); If ຕ is too hard to type, choose another short name. -- Simen |
January 24, 2010 Re: Confused by struct constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas Attachments:
| auto s = initArray!( S )( ຕ( 1, "a" ), ຕ( 2, "b" ), ຕ( 3, "c" ) );
>
> If ຕ 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
|
Copyright © 1999-2021 by the D Language Foundation