On Monday, 13 March 2017 at 00:51:27 UTC, Adam D. Ruppe wrote:
On Monday, 13 March 2017 at 00:02:12 UTC, Inquie wrote:
I just figured it didn't work in general, but seems to be an
issue with appending.
Oh, it is because of the implicit construction thing, see my
answer here to learn more:
http://stackoverflow.com/a/42285015/1457000
You can construct the named tuple from a tuple() but you can't
convert one to another since the names change the type.
I don't think the language has a solution with this since you
can't implicit construct nor overload operators on built in
arrays (if it is a custom array, you can do an opOpAssign).
What you could do is
alias ShortName = Tuple!(int, "A");
ShortName[] a;
a ~= ShortName(3);
... of course, at that point, you can also just use a regular
struct too...
Yeah, so, surely though we can extract the names from the
variable and then supply those like I mentioned?
Tuple!(int, "A")[] x;
x ~= tuple!(ExtractTupleNames!x)(3);
which would be equivalent to
x ~= tuple!("A")(3)
which, of course, works.
ExtractTupleNames is a template that surely can get the names
from x? Knowing it's type and that every other element of the
type is a "name" it should be able to get the names then provide
them to tuple? From there, we could redefine tuple to do this
automatically as
x ~= tuple!x(3)
? Seems like it would probably be rather trivial with a bit of
template code?
Ok, I did this real quick, maybe you can see how to improve it
and reduce verbosity:
import std.typecons, std.typetuple, std.meta, std.string,
std.array, std.range;
template ExtractTupleNames(T)
{
string fix()
{
enum q = (T.stringof[7..$-3]);
return "alias ExtractTupleNames = AliasSeq!("~q~");";
}
mixin(fix());
}
void main(string[] argv)
{
Tuple!(int, "A", double, "B")[] x;
x ~= tuple!("A", "B")(3, 5.0);
x ~= tuple!(int, "A", double, "B")(3, 5.0);
x ~= tuple!(ExtractTupleNames!(typeof(x)))(3, 5.0);
}
The goal would be to not have to specify the long string each
time.
e.g., the third line would be either
x ~= tuple!(x)(3, 5.0);
or
x ~= tuple!typeof(x)(3, 5.0);
It would be nice if we could pass a "run time" variable since we
are only going to use it's type in the first place(avoids having
to specify the typeof at the call point).
I realize that we will probably have to redefine tuple but I'm ok
with that as it only makes it more robust.