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]));
}
}