www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Static opCall for templated structs

reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
I often want to offer users a pretty way to create the templated structs=
 I  =

use, and I find it complexifying to have to place such prettification  =

outside the struct itself. For instance:

   struct foo(T)
   {
     T data;

     static foo!(U) opCall(U)(U u)
     {
       foo!(U) result;
       result.data =3D u;
       return result;
     }
   }

Seeing as the static opCall is T agnostic, it would be nice to be able t=
o  =

use it like:

   auto f =3D foo(4);

However, that does of course not work, I need to write:

   auto f =3D foo!(typeof(4))(4);

or place the static opCall outside the struct:

   foo!(T) Foo(T)(T t)
   {
     foo!(T) result;
     result.data =3D t;
     return result;
   }

   struct foo(T)
   {
     T data;
   }

Now, the first workaround is ugly, and the latter requires a different  =

name for the constructing function, which is not quite as ugly, but stil=
l  =

not as good as it should be.

...I'm starting to think this might be more of a feature request than a =
 =

call for help, but oh well.

Is there a way to make this work in current D2.0, so that I can simply u=
se  =

the first syntax?

--Simen
Apr 15 2008
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Simen Kjaeraas wrote:
 I often want to offer users a pretty way to create the templated structs 
 I use, and I find it complexifying to have to place such prettification 
 outside the struct itself. For instance:
 
   struct foo(T)
   {
     T data;
 
     static foo!(U) opCall(U)(U u)
     {
       foo!(U) result;
       result.data = u;
       return result;
     }
   }
 
 Seeing as the static opCall is T agnostic, it would be nice to be able 
 to use it like:
 
   auto f = foo(4);
 
 However, that does of course not work, I need to write:
 
   auto f = foo!(typeof(4))(4);
 
 or place the static opCall outside the struct:
 
   foo!(T) Foo(T)(T t)
   {
     foo!(T) result;
     result.data = t;
     return result;
   }
 
   struct foo(T)
   {
     T data;
   }
 
 Now, the first workaround is ugly, and the latter requires a different 
 name for the constructing function, which is not quite as ugly, but 
 still not as good as it should be.
 
 ...I'm starting to think this might be more of a feature request than a 
 call for help, but oh well.
 
 Is there a way to make this work in current D2.0, so that I can simply 
 use the first syntax?

Yeh, I think that's a feature request, but a good one. If type inferencing were enhanced then you could hope for this to work: struct foo(T) { T data; static foo opCall(T u) { foo result; result.data = u; return result; } } And then foo(4) would deduce the type of the foo struct from the type of the opCall argument. But D's inference isn't that smart yet. Definitely an enhancement worth having though, I think. I can't think of any better workaround than your out-of-struct factory function. --bb
Apr 15 2008