Generic method that takes in either delegate or function

Jonathan M Davis jmdavisProg at
Wed Jan 12 00:47:16 PST 2011

On Wednesday 12 January 2011 00:21:54 %u wrote:
> Hi,
> Is there any way to specify a parameter as "something that can be called
> with parameter types A, B, C and that returns a value of type D", without
> caring whether it's a delegate, a function, or an object that overloads
> opCall? (This might require the use of templates, but I still can't figure
> it out...)
> Thank you!

Take this example from my proposed std.unittests which is currently under 

void assertPred(alias pred, string msg = null, string file = __FILE__, size_t 
line = __LINE__, T...)
               (T args)
    if(isCallable!pred &&
       is(ReturnType!pred == bool) &&
       __traits(compiles, pred(args)) &&
    immutable result = pred(args);

        string argsStr;

        if(args.length > 0)
            foreach(value; args)
                argsStr ~= format("[%s], ", to!string(value));

            argsStr.popBackN(", ".length);
            argsStr = "none";

            throw new AssertError(format("assertPred failed: arguments: %s.", 
argsStr), file, line);
            throw new AssertError(format("assertPred failed: arguments: %s: %s", 
argsStr, msg), file, line);

The combination of alias, isCallable, ReturnType, and __traits(compiles) does 
the trick. isCallable guarantees that pred is callable, but it doesn't care how. 
ReturnType guarantees that the return type is bool. And __traits(compiles, 
pred(args)) guarantees that pred can be called with the given arguments.

- Jonathan M Davis

More information about the Digitalmars-d-learn mailing list