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.






Reply via email to