How to declare "type of function, passed as an argument, which should have it's type inferred"? (or if D had an "any" type)
Gavin Ray
user at example.com
Mon Mar 29 17:46:13 UTC 2021
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.
More information about the Digitalmars-d-learn
mailing list