Constraining template with function signature
cy via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Jun 9 12:08:52 PDT 2016
The other way is better, but since you asked...
On Wednesday, 8 June 2016 at 01:42:55 UTC, Carl Vogel wrote:
> Now, I can use something like isCallable std.traits to make
> sure the predicate is a Callable, and there are various
> function traits in the module that I could combine with `is`
> clauses to enforce the signature it seems, but that seems very
> clunky. Is there a better way?
You could put all that stuff into one single template like this:
template isCompatibleCallable(alias Src, alias Dest) {
static assert(isSomeFunction!Src || isCallable!Src,
"Source is not callable");
static assert(isSomeFunction!Dest || isCallable!Dest,
"Destination is not callable");
static assert(is(ParameterTypeTuple!Src ==
ParameterTypeTuple!Dest),
"Type Tuples differ");
pragma(msg,ParameterStorageClassTuple!Src ==
ParameterStorageClassTuple!Dest);
static assert(ParameterStorageClassTuple!Src ==
ParameterStorageClassTuple!Dest,
"Storage classes differ");
static assert(is(ReturnType!Src == ReturnType!Dest),
"Return type differs");
immutable bool isCompatibleFunction = true;
}
That works if you have a "default action" when the callable isn't
specified, because you can match the Callable to the default one.
So like...
bool default_less(T)(T a, T b) { return a < b; }
T[] sortArray(alias less = default_less!T, T)(T[] arr)
if(isCompatibleCallable(less,default_less!T) { ... }
But it's probably clearer to use that is(typeof({ how this
function will be called })) trick.
More information about the Digitalmars-d-learn
mailing list