Reputation: 174
Would anybody like to explain why this code is incorrect for template functions but works well for ordinary function. For instance, if we replace std::copy
with non-template functions, no problem.
How to change the code and make it valid for both template and non-template functions?
auto functionSpan = [](auto&& func, auto&&... args) {
auto t1 = std::chrono::high_resolution_clock::now();
std::forward<decltype(func)>(func)(std::forward<decltype(args)>(args)...);
auto t2 = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count();
};
vector<int> vec {1,2,3,4,5,6,7,8,9};
functionSpan(std::copy, vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));
Upvotes: 1
Views: 61
Reputation: 7828
The problem is that std::copy
(and really, any template
function) isn't a regular function, so the compiler can't derive it. What the compiler needs is a real function, although you could stamp out the the arguments to std::copy
.
The issue with explicitly stamping out the arguments is your code isn't generic anymore, plus it's tedious and error-prone when dealing with iterators. Instead, I'd suggest changing your function signatures a bit:
auto functionSpan = [](auto&& fn) {
auto t1 = std::chrono::high_resolution_clock::now();
fn();
auto t2 = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count();
};
auto copy_helper = [](auto && ... args) {
return [args...]() {
std::copy(args...);
};
};
std::vector<int> vec {1,2,3,4,5,6,7,8,9};
functionSpan(copy_helper(vec.begin(), vec.end(),
std::ostream_iterator<int>(std::cout, " ")
));
This compiles for me (I removed the forward
ing to make my life simpler) and runs as expected. You'll have to write a specific helper for each template
function, but it's less boilerplate than trying to stamp out the template
arguments since you still get most of the type deduction.
Upvotes: 0
Reputation: 38624
std::copy does not refer to a single function. You need to specify std::copy<Type>
Upvotes: 1