www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why I can't pass to datetime.benchmark function with parameters?

reply Suliman <evermind live.ru> writes:
Working:
void main()
{
  auto r = benchmark!(foo)(1);
}

void foo()
{

}


Do not working:
void main()
{
  auto r = benchmark!(foo())(1);
}

void foo()
{

}

Error: expression foo() is void and has no value
Do not working: void main() { auto r = benchmark!(4)(1); } void foo(int i) { writeln(i); } Why I second two variants do not compile?
Apr 23 2016
parent reply Anonymouse <asdf asdf.com> writes:
On Saturday, 23 April 2016 at 15:11:13 UTC, Suliman wrote:
 Working:
 void main()
 {
  auto r = benchmark!(foo)(1);
 }
[...]
 Do not working:
 void main()
 {
  auto r = benchmark!(foo())(1);
 }
[...]
Error: expression foo() is void and has no value
Do not working: void main() { auto r = benchmark!(4)(1); }
[...]
 Why I second two variants do not compile?
The first template argument to std.datetime.benchmark is the function you want to benchmark, which you have specified correctly in your first example. benchmark!(function)(times). In the second one you're first calling foo() to pass *the value it returns* as template argument to benchmark. Since it returns void, you're essentially calling benchmark!(void)(1), not what you want. If foo() had returned a function pointer it would likely have worked. In the third example you're providing an integer as the function to benchmark, and foo is never mentioned. The documentation explicitly says that the function must not take any parameters. I'm not sure why, but that's how it was designed. That said, you can easily work around it by making an intermediate function/delegate that passes the arguments you want, or a lambda. Unsure whether this incurs any performance hits, if it doesn't inline. You can make a wrapper like in http://dpaste.dzfl.pl/c856b9be53e9 but the extra argument has to be known during compilation.
Apr 23 2016
parent reply Suliman <evermind live.ru> writes:
In the third example you're providing an integer as the function 
to benchmark, and foo is never mentioned.
My error. I mean it should be: auto r = benchmark!(foo(4))(1); But thanks for answer!
Apr 23 2016
parent David Nadlinger <code klickverbot.at> writes:
On Saturday, 23 April 2016 at 18:52:30 UTC, Suliman wrote:
 My error. I mean it should be:
 auto r = benchmark!(foo(4))(1);

 But thanks for answer!
This would use the result of foo(4) as the template parameter. Use e.g. { foo(4); } instead (a function that calls foo with the desired argument). - David
Apr 24 2016