On 2011-07-05 03:11, Ali Çehreli wrote:
On Tue, 05 Jul 2011 02:44:03 +0200, Loopback wrote:

I've researched a bit though I still haven't come up with a solution.
Since the problem lies within (the most simple) constructor, I tried to
modify it for another outcome. If I supplied a generic parameter to the
pre-constructor the "Cannot evaluate at compile time" message
disappeared but two new errors appeared instead.

This is what I modified:

this()(float x, float y, float z) =>  this(T)(float x, float y, float z)

If I use this code instead, I get two other errors appearing:

Error: template test.DVECTOR2.__ctor(T) does not match any function
template declaration

This error and another one (individual to each statement) appears in the
following code statements:


Error: template test.DVECTOR2.__ctor(T) cannot deduce template function
from argument types !()(float,float)
DVECTOR2 m_zoom = DVECTOR2(2f, 2f);

Error: template test.DVECTOR2.__ctor(T) cannot deduce template function
from argument types !()(immutable(float),const(float)) immutable
DVECTOR2 m_UP_DIR = DVECTOR2(0f, 1f, 0f);

Here is a simple form of the same problem:

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.

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?
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); }

        // Inverse the vector
        DVECTOR2 opUnary(string op)() if(op == "-") { return DVECTOR2(-x, -y); }
        
        // Binary Operations
        DVECTOR2 opBinary(string op, T)(T rhs) if(Accepts!T)
        {
                enum rx = isScalar!T ? "" : ".x";
                enum ry = isScalar!T ? "" : ".y";
                
                return DVECTOR2(mixin("x" ~ op ~ "rhs" ~ rx), mixin("y" ~ op ~ 
"rhs" ~ ry));
        }
        
        // Right Binary Operator
        DVECTOR2 opBinaryRight(string op, T)(T lhs) if(Accepts!T) { return 
DVECTOR2(lhs).opBinary!op(this); }
        
        // Assign Operator
        ref DVECTOR2 opAssign(T)(T rhs) if(Accepts!T)
        {
                static if(isScalar!T)
                        x = y = rhs;
                        
                else
                {
                        x = rhs.x;
                        y = rhs.y;
                }
                
                return this;
        }
        
        // In-Place Assignment Operators
        ref DVECTOR2 opOpAssign(string op, T)(T rhs) if(Accepts!T) { 
return(this.opAssign(opBinary!op(rhs))); }

        // Cast Operators (to D3DXVECTOR2 and POINT)
        T opCast(T)() if(Accepts!T && !isScalar!T) { return T(x, y); }
}

unittest
{
        // This fails, saying that the expression cannot be
        // evaluated at compile time.
        immutable DVECTOR2 test = DVECTOR2(0f, 1f, 0f);
}

Reply via email to