Thread overview
variadic templates and out/inout
Dec 19, 2006
Tyro
Dec 19, 2006
Kirk McDonald
Dec 19, 2006
Tyro
Dec 19, 2006
Tyro
Dec 19, 2006
Tyro
Dec 19, 2006
Kirk McDonald
Dec 21, 2006
Tyro
December 19, 2006
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
December 19, 2006
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;
  }
}

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org
December 19, 2006
Thanks for responding. Actually, I've already tried that. The complier complains that it's looking for an "Integer constant expression" instead of "cast(int)i".

------------
Andrew Edwards
December 19, 2006
Sorry about that, I hadn't taken the time to update my copy of DMD since v0.173.

Thanks for the info!

------------
Andrew Edwards
December 19, 2006
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?

-- 
Andrew C. Edwards
-----------------------------------------------------
The truth we call D, has passed through three stages:
  First, it was ridiculed;
  Then, it was violently opposed; and
  And now, it is being accepted as self-evident.
Consequently:
  C/C++ is rapidly approaching Stage 5 (being forgotten)!
December 19, 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
December 21, 2006
Ammazing! I tried several variation of is() before I made that post but couldn't come up with it. Probably because I couldn't bring myself to leaving "double" on its own and didn't find the documention to explain it.

Thank you again.

--
Andrew Edwards