zip with fieldTuple

Brad Anderson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jun 6 15:27:08 PDT 2014


On Friday, 6 June 2014 at 22:16:36 UTC, John wrote:
> So let's say I'm trying to create a really simple ORM. I have a 
> struct:
>
> struct foo {
> 	int a;
> 	float b;
> }
>
> I can iterate over the struct elements with the traits 
> FieldTypeTuple!foo, I can iterate over the the string that 
> represents the elements I want to shove in the struct, but when 
> I try to loop over *both* of these at the same time with 
> zip(...) I get an error. Code:
>
> void main() {
> 	string test = "1,2.0";
>     foreach (t, value; zip(FieldTypeTuple!foo, 
> test.split(","))) {
>     	writeln(to!t(value));
>     }
> }
>
> Error:
>
> src\orm.d(13): Error: template std.range.zip does not match any 
> function template declaration
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\range.d(3808): 
> Error: template std.range.zip cannot deduce template function 
> from argument types !()((int, float),string[])
>
> I get what the error message is saying, but I have no idea how 
> to fix the code to do what I want. I tried to look up what the 
> FieldTypeTuple actually returns but it's calling a method on 
> the generic type T called tupleOf(), which I can't seem to find 
> (in that file or as a general function on object). I'm not sure 
> if it's actually a range? I assumed it would be a range of some 
> kind, and each of the elements would have a supertype of 
> something like 'type' since that's what they are. It could 
> infer that now you have two ranges, one of 'type' and one of 
> 'string'.
>
> If I'm able to foreach over two things, shouldn't I be able to 
> foreach over the paired ranges with zip? It seems so simple...

foreach-ing over a typetuple is very different from doing it over 
regular variables. The compiler basically expands the foreach 
into several blocks of code (without introducing scope, I 
believe).

So you are mixing compile time values and runtime values in a 
weird way. Types can't be zipped up with runtime values (or 
zipped up at all without some extra work).

One way to do what you want is to foreach over the typetuple and 
use the index to index into the runtime values like this:

struct foo {
	int a;
	float b;
}

void main() {
	import std.range, std.traits, std.stdio, std.conv;
	string test = "1,2.0";
	auto test_split = test.split(",");
     foreach (i, T; FieldTypeTuple!foo) {
     	writeln(to!T(test_split[i]));
     }
}


More information about the Digitalmars-d-learn mailing list