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 review: 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)) && isPrintable!T) { immutable result = pred(args); if(!result) { string argsStr; if(args.length > 0) { foreach(value; args) argsStr ~= format("[%s], ", to!string(value)); argsStr.popBackN(", ".length); } else argsStr = "none"; if(msg.empty) throw new AssertError(format("assertPred failed: arguments: %s.", argsStr), file, line); else 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