State logger for optimization problems I am working on a C++ project for solving a class of optimization problems. The project will be header-only, and for now, I would like to stay with C++11 (so, not fold-expressions).

To be able to support some basic logging functionality, I have started writing the below logger class. Any comment/feedback is welcome. However, I would like to ask specifically about your suggestions on how to restructure the code, if at all, to make it more efficient.

#ifndef LOGGER_HPP_
#define LOGGER_HPP_

#include &lt;chrono&gt;
#include &lt;cstdint&gt;
#include &lt;type_traits&gt;
#include &lt;vector&gt;

namespace utility {
namespace logger {

template &lt;class float_t, bool log_x_v, bool log_g_v&gt; struct logger_t {
  template &lt;class InputIt1, class InputIt2&gt;
  void operator()(const std::size_t k, const float_t fval, InputIt1 xbegin,
                  InputIt1 xend, InputIt2 gbegin, InputIt2 gend) {
    tend = std::chrono::high_resolution_clock::now();
    const auto telapsed =
        std::chrono::duration&lt;float_t, std::chrono::milliseconds::period&gt;(
            tend - tstart);
    iterations.push_back(k);
    times.push_back(telapsed.count());
    fvalues.push_back(fval);
    log_x(xbegin, xend, std::integral_constant&lt;bool, log_x_v&gt;{});
    log_g(gbegin, gend, std::integral_constant&lt;bool, log_g_v&gt;{});
    tstart = std::chrono::high_resolution_clock::now();
  }

private:
  template &lt;class InputIt&gt;
  void log_x(InputIt xbegin, InputIt xend, std::true_type) {
    xvalues.emplace_back(xbegin, xend);
  }
  template &lt;class InputIt&gt; void log_x(InputIt, InputIt, std::false_type) {}
  template &lt;class InputIt&gt;
  void log_g(InputIt gbegin, InputIt gend, std::true_type) {
    gvalues.emplace_back(gbegin, gend);
  }
  template &lt;class InputIt&gt; void log_g(InputIt, InputIt, std::false_type) {}

  std::vector&lt;std::size_t&gt; iterations;
  std::vector&lt;float_t&gt; times;
  std::vector&lt;float_t&gt; fvalues;
  std::vector&lt;std::vector&lt;float_t&gt;&gt; xvalues, gvalues;
  std::chrono::time_point&lt;std::chrono::high_resolution_clock&gt; tstart{
      std::chrono::high_resolution_clock::now()},
      tend;
};

template &lt;class float_t&gt; using value = logger_t&lt;float_t, false, false&gt;;
template &lt;class float_t&gt; using decision = logger_t&lt;float_t, true, false&gt;;
template &lt;class float_t&gt; using gradient = logger_t&lt;float_t, false, true&gt;;
template &lt;class float_t&gt; using full = logger_t&lt;float_t, true, true&gt;;

} // namespace logger
} // namespace utility

#endif


Basically, the class is not complete, yet. I will be adding iterator support, read/write csv/binary functionality and some locking mechanism, later on, to be able to support thread-safe logging of values inside the logger.

Specifically, what I would like to ask is if I need to have some level of abstraction to make the unused private member variables disappear. The tag dispatch on log_x and log_g member functions seem to be OK when it comes to optimizing out the empty function calls, I hope. But then, when there is no logging needed for x and g, private member variables xvalues and gvalues are redundant. Should I care about them, or should I leave it as is for the sake of maintainability and ease of reading the code?
You could use a better name for the template argument float_t, maybe value_t 

Maybe you could combine both log functions as they are very similar:

template &lt;typename Container, typename InputIt&gt;
void log(Container &amp;c, InputIt begin, InputIt end, std::true_type) {
    c.emplace_back(begin, end);
  }