www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - variadic templates and out/inout

reply Tyro <nospam home.com> writes:
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
Dec 18 2006
parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
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
Dec 18 2006
next sibling parent reply Tyro <nospam home.com> writes:
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
Dec 18 2006
parent Tyro <nospam home.com> writes:
Sorry about that, I hadn't taken the time to update my copy of DMD
since v0.173.

Thanks for the info!

------------
Andrew Edwards
Dec 18 2006
prev sibling parent reply Tyro <ridimz yahoo.com> writes:
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)!
Dec 19 2006
parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
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
Dec 19 2006
parent Tyro <nospam home.com> writes:
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
Dec 20 2006