www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Template type deduced from struct ctor?

reply =?UTF-8?B?Ikx1w61z?= Marques" <luis luismarques.eu> writes:
Could this be made to work?

     struct S(T)
     {
         T x;

         this(T x)
         {
             this.x = x;
         }
     }

     void main()
     {
         int x = 42;
         auto s = S(x); // fails to deduce T
     }
Mar 27 2014
next sibling parent "Indigo Brown" <Indigo Brown.edu> writes:
On Thursday, 27 March 2014 at 17:42:24 UTC, Luís Marques wrote:
 Could this be made to work?

     struct S(T)
     {
         T x;

         this(T x)
         {
             this.x = x;
         }
     }

     void main()
     {
         int x = 42;
         auto s = S(x); // fails to deduce T
     }

Sure, it *could* work but I doubt it ever actually will. Instead, why not pass the type directly? auto s = S!(typeof(x))(x);? I know it's a little more work and not very pretty but it should solve the problem. Or, if your constructors are simple enough, maybe something like this would work struct S(alias X) { this() { this.x = X; } } ... auto s = S!(x);
Mar 27 2014
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Thursday, 27 March 2014 at 17:42:24 UTC, Luís Marques wrote:
 Could this be made to work?

     struct S(T)
     {
         T x;

         this(T x)
         {
             this.x = x;
         }
     }

     void main()
     {
         int x = 42;
         auto s = S(x); // fails to deduce T
     }

This is usually done via a "constructor function", that's the name of your struct, but with a lower case start letter. EG: //---- /// Some struct parameterized on T. struct MyStruct(T) { T x; this(T x) { this.x = x; } } /// convenience to build a MyStruct auto myStruct(T)(T t) { return MyStruct!T(t); } void main() { int x = 42; auto s = myStruct(x); // succeeds in deducing T } //---- This "old standing" trick predates D, and comes from C++, with functions such as //---- namespace std { pair<T1, T2> make_pair<T1, T2>(T1 t1, T2 t2) { return pair<T1, T2>(t1, t2); } } //----
Mar 27 2014
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Thursday, 27 March 2014 at 17:52:34 UTC, Indigo Brown wrote:
 Or, if your constructors are simple enough, maybe something 
 like this would work

 struct S(alias X)
 {
     this() { this.x = X; }
 }

 ...

 auto s = S!(x);

This is not the same, and will create a new template instantiation for every instance you use it with. Not recommended unless you know what you are doing.
Mar 27 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Thursday, 27 March 2014 at 17:42:24 UTC, Luís Marques wrote:
 Could this be made to work?

     struct S(T)
     {
         T x;

         this(T x)
         {
             this.x = x;
         }
     }

     void main()
     {
         int x = 42;
         auto s = S(x); // fails to deduce T
     }

struct S(T) { static if (is(T == int)) { this(double x) { } } static if (is(T == double)) { this(int x) { } } } auto s = S(42); // should it deduce T, huh, and to what? I believe it could work but too many complexities arise that need to be figured out, especially with overloading in mind so it is hardly worth the effort.
Mar 27 2014
prev sibling parent "anonymous" <anonymous example.com> writes:
On Thursday, 27 March 2014 at 17:59:36 UTC, Dicebot wrote:
 struct S(T)
 {
     static if (is(T == int))
     {
         this(double x) { }
     }
     static if (is(T == double))
     {
         this(int x) { }
     }
 }

 auto s = S(42); // should it deduce T, huh, and to what?

No, it shouldn't. You're not using T as the parameter type. Just like T can't be deduced here: void f(T)(double x) if(is(T == int)) {} void f(T)(int x) if(is(T == double)) {} f(42);
Mar 27 2014