variadic templates and out/inout

Kirk McDonald kirklin.mcdonald at gmail.com
Tue Dec 19 02:07:20 PST 2006


Tyro wrote:
> Kirk McDonald wrote:
> 
>> Tyro wrote:
>>
>>> The following compiles without any errors or warning. However it
>>> fails if line 12 is uncommented (error messages provided below). Is
>>> there a compelling reason why this should not work? If not, what
>>> are the possibilities of getting this implemented?
>>>
>>> void get(A...)(inout A a)
>>> {
>>>   foreach(inout t; a)
>>>   {
>>>     if(typeid(typeof(t)) is typeid(double))
>>>       t = 0.0;
>>>   }
>>> }
>>>
>>> void main()
>>> {
>>>   double d;
>>>   //get(d); // fails
>>> }
>>>
>>>
>>> /+
>>> Error messages:
>>>
>>> io.d(3): no storage class for t
>>> io.d(12): template instance io.get!(double) error instantiating
>>> +/
>>>
>>> ------------
>>> Andrew Edwards
>>
>>
>> There is no particular reason why this shouldn't work. However, there 
>> is a very simple workaround. Re-write 'get' like this:
>>
>> void get(A...)(inout A a)
>> {
>>   foreach(i, t; a)
>>   {
>>     if(typeid(typeof(t)) is typeid(double))
>>       a[i] = 0.0;
>>   }
>> }
>>
> 
> Further evaluation of the above has revealed that the assignment a[i] = 
> 0.0 is attempted prior to if(...) being evaluated. This causes the 
> function to fail if the type of the argument passed in does not match 
> that of the value being assigned. Is there any way around this?
> 

It's not that the assignment is attempted, it's that the code for it is 
generated. Since that code (a[i] = 0.0) isn't valid for some types, you 
need to make sure that line isn't even generated for the invalid types. 
(Welcome to compile-time metaprogramming!) Static if works nicely:

void get(A...)(inout A a)
{
   foreach(i, t; a)
   {
     static if(is(typeof(t) == double))
       a[i] = 0.0;
   }
}

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org



More information about the Digitalmars-d mailing list