I am trying to learn variadic tamplete functions, so I tried to make a function "timeIt" that takes another function and calls it.
#include <chrono>
#include <iostream>
#include <string>
std::string leftPad(std::string str, unsigned len, char c = ' ') {
if (str.length() >= len)
return str;
return std::string(len - str.length(), c) + str;
}
template <typename T, typename... Args, typename... Args2>
auto timeIt(T (*func)(Args...), Args2... args) {
namespace ch = std::chrono;
auto start = ch::high_resolution_clock::now();
func(args...);
auto end = ch::high_resolution_clock::now();
return ch::duration_cast<ch::microseconds>(end - start).count();
}
int main() {
std::cout << timeIt(&leftPad, "foo", 10) << std::endl;
return 0;
}
This only compiles if I explicitly pass the last argument as ' ', as in
timeIt(&leftPad, "foo", 10, ' ')
Is there any way to use the default argument in this case?
No need to do the heavy lifting yourself, that can already be done by lambda functions like this (foo captured by reference as example):
#include <chrono>
#include <iostream>
#include <string>
std::string leftPad(std::string str, unsigned len, char c = ' ') {
if (str.length() >= len)
return str;
return std::string(len - str.length(), c) + str;
}
// no need to do all the argument capturing for timing
// leave that to lambda functions
template <typename fn_t>
auto timeIt(fn_t fn) {
namespace ch = std::chrono;
auto start = ch::high_resolution_clock::now();
fn();
auto end = ch::high_resolution_clock::now();
return ch::duration_cast<ch::microseconds>(end - start).count();
}
int main() {
// use a lambda function
std::string foo{ "foo" };
std::cout << timeIt([&] { leftPad(foo, 10); }) << std::endl;
return 0;
}