Thank you all of you for your help!
Michael
On Sunday, 24 June 2012 at 06:49:38 UTC, Philippe Sigaud wrote:
The closest I came to the correct template is
template(alias F) timer {
auto timer {
auto start = Clock.currStdTime();
F();
return Clock.currStdTime() - time;
}
}
The problem with the template is I cannot pass any argument
into "F". How
should I fix this problem?
As Simendsjo said, you can use a function template to get what
you want and
a nicer syntax as the same time.
Slightly different code can be obtained by starting from the
above code:
template timer(alias F) // capture F's name
{
auto timer(Args...)(Args args) // there are your parameters
{
import std.datetime; // inner imports
auto start = Clock.currStdTime();
F(args);
return Clock.currStdTime() - start;
}
}
So it's a template that gets expanded into another template
with the same
name, a function.
Note that the construct:
template (T...)
{
T foo(T t) // some function that depends on the template
parameters
{
}
}
can get syntax sugar like this:
T foo(T...)(T t)
{
}
you can 'fuse' the external template and the inner code to get
a function
template. The same for classes and structs.
Now, for something a bit more hairy: Simendsjo's version and
mine are not
strictly equivalent:
- his version is simpler to type and to reason about. You
should use it,
it's the D way to do this kind of thing.
- mine (the two level templates) gets an interesting effect: I
can use the
first level only (getting the function name), keeping the
second level for
later:
// mine
alias timer!foo tfoo; // tfoo is the inner template, the
function template
/* a bit later */
tfoo(args1);
tfoo(args2);
import std.algorithm;
Args[] argsArray;
auto m = map!(tfoo)(argsArray); // applying tfoo on all
arguments groups
// Simendsjo:
timer!foo(args1);
timer!foo(args2); // You must provide 'foo' for each call.
Also, I am not entirely sure why I need to write "alias F"
instead of
just "F", any explanation would be appreciated.
Because in your case, you want to get the name, the symbol. So
use an alias
parameter. 'F' would be to deal with types, as Ali said.
For example:
auto foo(F, Args...)(F fn, Args args)
{
...
}
in this case, fn is passed as a runtime value of type F:
timer(&foo, args); // the compiler automatically deduces the
types of fn
and args.
Philippe