www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - simple template constraint - compile error.

reply "WhatMeWorry" <kheaser gmail.com> writes:
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?
Jun 07 2015
parent reply "anonymous" <anonymous example.com> writes:
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)
Jun 07 2015
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
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.
Jun 07 2015
prev sibling parent reply "WhatMeWorry" <kheaser gmail.com> writes:
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?
Jun 07 2015
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
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.
Jun 07 2015
prev sibling parent reply "WhatMeWorry" <kheaser gmail.com> writes:
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)...
Jun 07 2015
parent "WhatMeWorry" <kheaser gmail.com> writes:
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!
Jun 07 2015