On Tue, 05 Jul 2011 16:20:44 +0200, Loopback wrote: > On 2011-07-05 03:11, Ali Çehreli wrote:
>> struct S >> { >> this(T)(double d) >> {} >> } >> >> void main() >> { >> auto o = S(1.5); >> } >> >> Error: template deneme.S.__ctor(T) does not match any function template >> declaration >> Error: template deneme.S.__ctor(T) cannot deduce template function from >> argument types !()(double) >> >> The compiler is right: What should T be there? int? string? MyClass? >> >> I've realized again that I don't know how to specify the template >> parameter for the constructor. The following attempt fails as the >> compiler thinks S itself is a template: >> >> auto o = S!string(1.5); >> >> Error: template instance S is not a template declaration, it is a >> struct >> >> And if I try to be smart after the error message, this seg faults the >> compiler: >> >> auto o = S.__ctor!string(1.5); >> >> Ali > Hmm... Interesting. Thank you for clarifying and explaining that! > > I guess supplying T to the constructor when the parameters are already > known to avoid compiler errors is not a solution then. Seems to me as if > its only aggravates things. > > Though is there no solution nor any workarounds for this problem? I've > attempted to use two different types of constructors and both appeared > to be very limited, and I do not believe that this is the case. I don't want to look like brushing off the problem but having many constructors make the code complicated. For example, it may be confusing which constructor gets called here: auto d = DVECTOR2(1.5); Are we setting just x or both x and y? Especially when we know that DVECTOR2 is a struct and that structs have this feature of assigning default values to the trailing unspecified members (at least in some cases), I think a factory function would be better in this case: auto d = square_DVECTOR2(1.5); Now we know that both x and y will be 1.5. Same can be said for some of the other constructors. It is not difficult at all for the caller to give us what we want; and it is clearer: D3DXVECTOR2 d3; // ... auto d = DVECTOR2(d3.tupleof); (I think this is in line with Kevlin Henney's "Parameterize from Above" guideline/pattern/idiom/etc. :)) > If you use a generic constructor is there no possible way to use it in > cases where immutable and const is involved? Or is there a page that I > have missed perhaps? D2 has changed the meaning of inout to mean something like "templatize just the mutable/const/immutable qualification of the parameter" but it is not implemented fully yet. Look at "Inout Functions" on the Functions spec: http://d-programming-language.org/function.html > struct DVECTOR2 > { > // Controls that the parameter is a valid type template Accepts (T) { > enum Accepts = is(T == DVECTOR2) || is(T == float) || is(T == > D3DXVECTOR2) || is(T == POINT); } > > // Whether the parameter is a float or not > template isScalar(T) { enum isScalar = is(T == float); } > > // The Variables > float x = 0f; > float y = 0f; > > // Default Constructor > this()(float x, float y) > { > this.x = x; > this.y = y; > } > > // Float Constructor > this()(float xy) { this(xy, xy); } > > // Implement D3DXVECTOR2 and POINT support > this(T)(T arg) if (Accepts!T > && !isScalar!T) { this(arg.tupleof); } Ali