On Monday, 29 March 2021 at 16:31:49 UTC, Paul Backus wrote:
On Monday, 29 March 2021 at 16:20:59 UTC, Ali Çehreli wrote:
auto myFunc(F)(string name, F func)
{
// This condition could be a template constraint but they
don't
// support error messages.
static assert (is (Parameters!func == AliasSeq!(string)),
"'func' must be a callable that takes
'string'.");
return func(name);
}
void main() {
// One trouble with this "solution" is that for the compiler
to
// know the return type of the lambda, the parameter must be
// declared as 'string' (in this case).
writeln(myFunc("foo", (string a) => a ~ '.'));
}
Ali
Alternatively:
auto myFunc(F)(string name, F func)
{
static assert (__traits(compiles, (string s) => func(s)),
"'func' must be a callable that takes
'string'.");
return func(name);
}
void main() {
// No need to write out the argument type
writeln(myFunc("foo", a => a ~ '.'));
}
You can generalize this into a helper template:
enum bool isCallableWith(alias fun, ArgTypes...) =
__traits(compiles, (ArgTypes args) => fun(args));
Usage:
static assert(isCallableWith!(func, string));
------------------------------------------------------------------------
Ah that was even easier than I had made it out to be, thank you
folks!
The part about needing to define the argument types to the lambda
is no problem either (it was a silly transcription mistake on my
end).
I actually need those argument types for later, to generate code
based on them (translating D arg types -> a subset of C types,
for building a translated function signature string to give to
another app) so it works out =D
Much appreciated.