On Thursday, 8 October 2015 at 09:29:30 UTC, tcak wrote:
I am "trying" to write a function that takes an array of items, and returns the length of longest item.[code]size_t maxLength(A)( const A[] listOfString ) if( __traits( hasMember, A, "length" ) ){ return 0; // not implemented yet } [/code] I tried it with if( __traits( compiles, A.length ) ) as well. But compiler doesn't match it. writeln("Max Length: ", maxLength( ["foo", "123456789"] )); Compilers says it cannot deduce function from argument types ...I do not want to check whether the type "A" is string, char[], etc. As long as it has length (please do not put me into ranges, library functions etc as much as possible), I want the function to accept it.
I'm 99% sure something like __traits(hasMember, int[], "length" ) should evaluate to true. Please file a bug at issues.dlang.org I notice it also doesn't work for "ptr".
The correct workaround: __traits(compiles, A.init.length )); or __traits(compiles, listOfStrings.length ));A.length doesn't work because length is not a static member, so it's only accessible from an instance.
The __traits(compiles, ...) solution is actually more general because it will work if .length is implemented via UFCS and opDispatch.
FYI:If you want to check whether a statement will compile, as opposed to an expression, make a function/delegate out of it, e.g.:
__traits(compiles, { size_t n = A.init.length; });
to check that A has a member length that can be assigned to
size_t.
P.S. always check std.traits for solutions all your static reflection problems, there's a lot of good stuff in there.
