Thread overview
simple template constraint - compile error.
Jun 07, 2015
WhatMeWorry
Jun 07, 2015
anonymous
Jun 08, 2015
Adam D. Ruppe
Jun 08, 2015
WhatMeWorry
Jun 08, 2015
Adam D. Ruppe
Jun 08, 2015
WhatMeWorry
Jun 08, 2015
WhatMeWorry
June 07, 2015
Should be real simple. But adding a small template constraint causes compile failure.  I've got the following working code:

int arrayByteSize(T)(T[] someArray)
{
    ubyte[] arr = cast(ubyte[]) someArray;
    return arr.length;        // length is implicitly converted to bytes.
}

// running the following code:

GLfloat[] dynamicVerts = [0.0, 1.0,-1.0, -1.0, 1.0, -1.0 ];

int lengthInElements = dynamicVerts.length;
myLog!lengthInElements;
int sizeInBytes = dynamicVerts.arrayByteSize;
myLog!sizeInBytes;

// returns the correct results:

lengthInElements = 6
sizeInBytes = 24


However, when I try to add a simple constraint to the function like so:

int arrayByteSize(T)(T[] someArray) if (isDynamicArray(T))
{
    ubyte[] arr = cast(ubyte[]) someArray;
    return arr.length;        // length is implicitly converted to bytes.
}


I get Error: cannot pass type float as a function argument

After I comment out //int sizeInBytes = arrayByteSize(dynamicVerts);

everything compiles. I've been fighting this for hours.  Am I overlooking the obvious?



June 07, 2015
On Sunday, 7 June 2015 at 23:08:02 UTC, WhatMeWorry wrote:
> However, when I try to add a simple constraint to the function like so:
>
> int arrayByteSize(T)(T[] someArray) if (isDynamicArray(T))

You forgot an exclamation mark here. Make that: isDynamicArray!(T)
June 08, 2015
On Sunday, 7 June 2015 at 23:13:14 UTC, anonymous wrote:
>> int arrayByteSize(T)(T[] someArray) if (isDynamicArray(T))
>
> You forgot an exclamation mark here. Make that: isDynamicArray!(T)

Also, if you pass int[] to that function, for example, T will *not* be int[] - it will actually be int.

(T)(T[])

means take an array of T. If you pass int[], it is an array of int, so that's why T is just int instead of an array.

You probably want to remove that [] from the signature.
June 08, 2015
On Sunday, 7 June 2015 at 23:13:14 UTC, anonymous wrote:
> On Sunday, 7 June 2015 at 23:08:02 UTC, WhatMeWorry wrote:
>> However, when I try to add a simple constraint to the function like so:
>>
>> int arrayByteSize(T)(T[] someArray) if (isDynamicArray(T))
>
> You forgot an exclamation mark here. Make that: isDynamicArray!(T)

Thanks, but I still can't get out of the woods. I've distilled
everything down to the following:

------------------------------------------------------------------

int arrayByteSize(T)(T[] someArray)
{
    ubyte[] arr = cast(ubyte[]) someArray;
    return arr.length;
}

int i = arrayByteSize(dynamicArray);  // works with above function.

------------------------------------------------------------------

However, if I just add a constraint to the function template

int arrayByteSize(T)(T[] someArray)
    if (isDynamicArray!(T))
{
    ubyte[] arr = cast(ubyte[]) someArray;
    return arr.length;
}

int i = arrayByteSize(dynamicArray); // Same call - all hell breaks loose.

Error arrayByteSize(T)(T[] someArray) if (isDynamicArray!T)
Error: template compilelinkshaders.arrayByteSize cannot deduce function from argument types !()(float[]), candidates are:

Why would a working function call stop working just because a constraint was added to the function?







June 08, 2015
On Monday, 8 June 2015 at 04:02:26 UTC, WhatMeWorry wrote:
> Why would a working function call stop working just because a constraint was added to the function?

because T is float... which isn't a dynamic array, so the constraint doesn't match. Just remove the [] after T[] in your signature and you should be ok.
June 08, 2015
On Monday, 8 June 2015 at 04:02:26 UTC, WhatMeWorry wrote:
> On Sunday, 7 June 2015 at 23:13:14 UTC, anonymous wrote:
>> On Sunday, 7 June 2015 at 23:08:02 UTC, WhatMeWorry wrote:
>>> However, when I try to add a simple constraint to the function like so:
>>>
>>> int arrayByteSize(T)(T[] someArray) if (isDynamicArray(T))
>>
>> You forgot an exclamation mark here. Make that: isDynamicArray!(T)
>
> Thanks, but I still can't get out of the woods. I've distilled
> everything down to the following:
>
> ------------------------------------------------------------------
>
> int arrayByteSize(T)(T[] someArray)
> {
>     ubyte[] arr = cast(ubyte[]) someArray;
>     return arr.length;
> }
>
> int i = arrayByteSize(dynamicArray);  // works with above function.
>
> ------------------------------------------------------------------
>
> However, if I just add a constraint to the function template
>
> int arrayByteSize(T)(T[] someArray)
>     if (isDynamicArray!(T))
> {
>     ubyte[] arr = cast(ubyte[]) someArray;
>     return arr.length;
> }
>
> int i = arrayByteSize(dynamicArray); // Same call - all hell breaks loose.
>
> Error arrayByteSize(T)(T[] someArray) if (isDynamicArray!T)
> Error: template compilelinkshaders.arrayByteSize cannot deduce function from argument types !()(float[]), candidates are:
>
> Why would a working function call stop working just because a constraint was added to the function?

Oops, I posted before I say Mr. Ruppe's comment.

Also, if you pass int[] to that function, for example, T will
*not* be int[] - it will actually be int.

(T)(T[])

means take an array of T. If you pass int[], it is an array of
int, so that's why T is just int instead of an array.

You probably want to remove that [] from the signature.

------------------------------------------------------------

My code seems to be working fine, or is that just by accident?

float[] dynamicArray = [1.0, 0.0, 1.0];
int i = arrayByteSize(dynamicArray);
myLog!dynamicArray;

dynamicArray = [1, 0, 1]

------------------------------------------------------------

I was trying to draw inspiration from the TDPL with Andrei's function
T[] find(T, E) (T[] haystack, E needle)...

June 08, 2015
Just a recap. Here's the final fix.  Thanks to Anonymous and Adam.


int arrayByteSize(T)(T someArray) if (isDynamicArray!(T))
{
    ubyte[] arr = cast(ubyte[]) someArray;
    return arr.length;
}

float[] dynamicArray = [1.1, 3.0, 1.0, 7.3];
sizeInBytes = arrayByteSize(dynamicArray);
lengthInElements = dynamicVerts.length;
myLog!dynamicArray;
myLog!lengthInElements;
myLog!sizeInBytes;


dynamicArray = [1.1, 3, 1, 7.3]
lengthInElements = 6
sizeInBytes = 16

And

float[3] staticArray = [3.0, 2.0, 1.0];
sizeInBytes = arrayByteSize(staticArray);  // Does not Compile!