Variadic template arguments unpacking

TommiT tommitissari at hotmail.com
Sat Jul 6 10:42:55 PDT 2013


On Saturday, 6 July 2013 at 15:23:40 UTC, Artur Skawina wrote:
> On 07/06/13 14:21, Max Strakhov wrote:
>> Artur, if i use your solution like
>> 
>> printf("...", ForEach!(val => 
>> conv(val).c_str())(values).tuple);
>> 
>> Than i would get a crash, because all the tuple elements would 
>> be char*'s, pointing to already freed memory, as std::string's 
>> destructor gets called each time right after alias function 
>> exits. Ths is what c++ unpacking operator for: i actually 
>> return a packed list of std::string's, apply .c_str() to each 
>> and than unpack the list to current context.
>
> Can you show some simple code that exhibits the problem?
>
> artur

import std.stdio;

template _TypeMap(alias MAP, size_t N, TS...) {
   static if (N<TS.length)
       alias _TypeMap = _TypeMap!(MAP,
                                  N+1,
                                  TS[0..N],
                                  typeof(MAP(TS[N].init)),
                                  TS[N+1..$]);
   else
       alias _TypeMap = TS;
}
template TypeMap(alias MAP, TS...) {
  alias TypeMap = _TypeMap!(MAP, 0, TS);
}

struct _ForEach(alias MAP, TS...)
{
   TypeMap!(MAP, TS) tuple;

   this(TS values)
   {
       foreach (i, ref v; values)
           tuple[i] = MAP(v);
   }
}

auto ForEach(alias MAP, TS...)(TS ts)
{
   return _ForEach!(MAP, TS)(ts);
}


int[2] getArray(int n)
{
     int[2] data = n;
     return data;
}

void foo(R...)(R ranges)
{
     foreach (range; ranges)
         foreach (value; range)
             write(value, " ");
}

void main()
{
     // Expecting this to print: 1 1 2 2 3 3
     foo(ForEach!(a => getArray(a)[])(1, 2, 3).tuple);
     // ... but it prints random garbage
}

Notice that there were a couple of typos in _TypeMap.


More information about the Digitalmars-d-learn mailing list