0

i have read different approaches howto measure the time of functions here at stackflow. I want to be able to call a timemeasure function for all functions of my program and wrote a little helper class :

// helper.h

class Helper
{
public:
   Helper();
   ~Helper();

   template<class F, typename...Args>
   double funcTime(F func, Args&&... args);
};

// helper.cpp:
#include "Helper.h"
#include <chrono>
#include <utility>

typedef std::chrono::high_resolution_clock::time_point TimeVar;
#define duration(a) std::chrono::duration_cast<std::chrono::milliseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

template<typename F, typename... Args>
double Helper::funcTime(F func, Args&&... args)
{
 TimeVar t1 = timeNow();
 func(std::forward<Args>(args)...);
 return duration(timeNow() - t1);
}

The same code works perfect if you call it within the same class, but generates the LNK2019 error if i call it with the main.cpp. The goal is to wrap this functions so, that i can call it with any of my functions. What i am doing wrong here ?

// main.cpp
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include "Helper.h"

using namespace std;

int countWithAlgorithm(string s, char delim) {
   return count(s.begin(), s.end(), delim);
}

int main(int argc, const char * argv[]) 
{ 
 Helper h;
 cout << "algo: " << h.funcTime(countWithAlgorithm, "precision=10", '=') << endl;
 system("pause");
 return 0;
}
biohell
  • 304
  • 3
  • 14
  • Place the definition of the template function `Helper::funcTime()` in the header file since, practically, most compilers cannot instantiate the template functions used in `Main.cpp` otherwise (there are ways avoid doing that, but you're not using them). Also, ensure you list both `helper.cpp` and `Main.cpp` in the build - just including `header.h` does not magically ensure the program is built with the functions that are defined (implemented) in `helper.cpp` unless you specifically build `helper.cpp` (i.e. produce the object file, and link that object file into the executable). – Peter Feb 10 '19 at 13:06
  • You can't separate implementation and header in template meta programming. Merge `helper.h` and `helper.cpp` into `helper.h` only. You can kinda "separate" them but the implementation will not be compiled into object file, and its extension shouldn't be `.cpp`, `.cxx`, or `.cc` etc. – tnt Feb 10 '19 at 13:19
  • You said there are ways to avoid doing that. Can you clarify that to me ? – biohell Feb 10 '19 at 13:20
  • Read: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – tnt Feb 10 '19 at 13:22

1 Answers1

0

Thank you both for pointing my in the right direction. I was aware about the fact that most compilers cannot instantiate the template functions, but not sure how to avoid that. tntxtnt comment helped me to find a solution in a merged helper.h:

//helper.h
//
#pragma once

#include <chrono>

typedef std::chrono::high_resolution_clock::time_point TimeVar;

#define duration(a) std::chrono::duration_cast<std::chrono::nanoseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

 class Helper
 {
 public:
   Helper();
   ~Helper();

 template<class F, typename...Args>
 double funcTime(F func, Args&&... args)
 {
    TimeVar t1 = timeNow();
    func(std::forward<Args>(args)...);
    return duration(timeNow() - t1);
 }
};

I thank you for your quick help !

biohell
  • 304
  • 3
  • 14