c++variadic-templatesdefault-arguments

Call function with default arguments inside a variadic function in c++


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?


Solution

  • 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;
    }