As we probably have to wait a bit until std::future::then is implemented I'm trying currently to write a very simple task wrapper the problem is calling the callback function. Lets say we have a class like:
template<typename... ARG>
class Task
{
public:
typedef std::function<void(ARG...)> task_func_t;
Task() {}
void then(task_func_t callback) { this->callback_ = callback; }
void finish(ARG... arguments)
{
this->callback_(std::forward<ARG>(arguments)...);
}
void operator()(ARG... arguments)
{
this->callback_(std::forward<ARG>(arguments)...);
}
private:
task_func_t callback_;
};
and lets assume the following usage:
std::shared_ptr<Task<int>> sum(int n1, int n2)
{
auto ptr = std::make_shared<Task<int>>();
myPool.process([n1, n2, ptr]
{
(*ptr.get())(n1 + n2);
}
return ptr;
}
void test()
{
sum(5, 6)->then([](int sum) { std::cout << "Sum is " << sum << std::endl };
}
I sometimes have the problem the callback is called before the function is actually set. I know I could check as long as the callback is invalid but I don't really like this solution so are there other smart solutions? I actually thought about doing it like this:
return task.before(do prepare work);
.then(process result)
So then It would call the the create thread when linking is done in then. The perfect solution would be something which calls then before as requirement but I think Its actually impossible as long I want this design.
You could wait on a condition variable. Make it a member of the task class and signal it after setting the function.
With future, you may do something like:
(then implementation from implementing-futurethen-equivalent-for-asynchronous-execution-in-c11)
template <typename Fut, typename Work>
auto then(Fut f, Work w) -> std::shared_future<decltype(w(f.get()))>
{
return std::async([=]{ w(f.get()); });
}
std::shared_future<int> sum(int a, int b)
{
return std::async([](int a, int b) { return a + b; }, a, b);
}
int main() {
then(sum(40, 2), [](int n) {std::cout << "Sum is " << n << std::endl;}).wait();
return 0;
}
Live example
Related
I have a question on callbacks. Previously, I am associating my callbacks to a class Q
class Q{
using Callback = std::function<void(char*, int)>;
Q:Q();
Q:~Q();
void Q::RegisterCB(Callback callbackfunc)
{
callback_func = callbackfunc;
}
void Q:someEvent()
{
callback_func();
}
};
void handleCallback( char*, int)
{
// perform some routine
}
// from my main file
int main()
{
Q q;
q.RegisterCB(&handleCallback);
}
It works well for me. However, when I need to transfer the handleCallback function to another class for cleaner code. I have problem with using same code
class R{
void R::handleCallback( char*, int)
{
// perform some routine
}
void R::someOp()
{
// q is some member variables of R
q.RegisterCB(&R::handleCallback, this);
}
};
However, i run into some problems of saying there is a "no matching function for call to .....". I thought it was just simply assigning from function name to class function name
May I have a hint to where I might go wrong?
Regards
&R::handleCallback has the type void (R::*)(char*, int), which is not convertible to std::function<void(char*, int)>.
Also, RegisterCB takes one argument, not two.
The most straightforward fix is to wrap the call in a lambda function,
q.RegisterCB([this](char* p, int x) { handleCallback(p, x); });
Example on how to use a lambda function to register a member function of an instance of R as event handler. (I replaced char* with string_view out of habit, it's not essential for this example). The use of "const" wherever you can is a recommendation.
#include <functional>
#include <string_view>
#include <iostream>
class Q
{
public:
// use const arguments, the callback is not supposed to change them
// just passing information on to callback
using callback_t = std::function<void(const std::string_view&, const int)>;
// initialize callback with a (lambda) function that does nothing
// this prevents the need for a check if callback has been set or not
// (Pattern : Null Strategy)
Q() :
m_callback_func( [](const std::string_view&,const int) {} )
{
}
~Q() = default;
void RegisterCallback(callback_t fn)
{
m_callback_func = fn;
}
void Event(const std::string_view& string, const int value)
{
m_callback_func(string,value);
}
private:
callback_t m_callback_func;
};
void handleCallback(const std::string_view& string, const int value)
{
std::cout << string << ", " << value << "\n";
}
class R
{
public:
void handleCallback(const std::string_view& string, const int value)
{
std::cout << string << ", " << value << "\n";
}
};
// from my main file
int main()
{
Q q1;
q1.RegisterCallback(handleCallback);
q1.Event("Hello", 42);
// to pass a callback to an instance of a class
// you can use a lambda function https://en.cppreference.com/w/cpp/language/lambda
R r;
Q q2;
q2.RegisterCallback([&r](const std::string_view& string, const int value)
{
r.handleCallback(string,value);
});
q2.Event("World",21);
return 0;
}
How to appropriately cache userData that is generated from user's callbackBegin() and send it to user's callbackEnd().
Simple version (No userData - demo)
I want to create a complex database that support callback. For MCVE, let's say it is MyArray.
Here is a simple array class that supports callback but no userData.
#include <iostream>
template<class Derived>class MyArray{ //library - I design it.
public: void push_back(int s){
static_cast<Derived*>(this)->callbackBegin(s);
//do something about array
static_cast<Derived*>(this)->callbackEnd(s);
}
//other fields / functions
};
class Callback : public MyArray<Callback>{ //user's class
public: void callbackBegin(int s){
std::cout<<"callbackBegin"<<std::endl;
}
public: void callbackEnd(int s){
std::cout<<"callbackEnd"<<std::endl;
}
};
int main() {
Callback c;
c.push_back(5); //print: callbackBegin callbackEnd
return 0;
}
It works correctly.
The next step : I want to pass some userData from Callback::callbackBegin() to Callback::callbackEnd().
For example, userData is a clock time when Callback::callbackBegin() is called.
My poor solution (void*& userdata : demo)
Here is my attempt to implement it :-
#include <iostream>
#include <time.h>
template<class Derived>class MyArray{
public: void push_back(int s){
void* userData=nullptr; //#
static_cast<Derived*>(this)->callbackBegin(s,userData); //# ugly
//do something about array
static_cast<Derived*>(this)->callbackEnd(s,userData); //# ugly
}
};
class Callback : public MyArray<Callback>{
public: void callbackBegin(int s,void*& userData){ //#
userData=new clock_t(clock()); //# danger
std::cout<<"callbackBegin"<<std::endl;
}
public: void callbackEnd(int s,void*& userData){ //#
clock_t* userDataTyped=static_cast<clock_t*>(userData);
clock_t clock2=clock();
clock_t different=clock2 - (*userDataTyped);
std::cout<<"callbackEnd time(second)="
<<((float)different)/CLOCKS_PER_SEC<<std::endl;
delete userDataTyped; //# danger
}
};
int main() {
Callback c;
c.push_back(5); //print: callbackBegin callbackEnd time(second)=8.5e-05
return 0;
}
It also works correctly, but I believe it is a bad design (at various #) :-
new/delete in 2 places : potential memory leaking.
Strong pointer is preferred, but I don't know how to.
static_cast<clock_t*>(userData) is code-smell, at least for me.
(minor issue) an extra ugly parameter void*&
Question: What are design patterns / C++ magic to avoid such issues, while make MyArray concise, easy to use, maintainable (i.e. not much worse than the Simple version)?
Other notes:
In real cases, <5% of user's callback classes need userData.
Thus, I feel very reluctant to add void&* as an extra parameter.
Clarify: (edited) The minority cases usually need different types of userData e.g. Callback1 need clock_t, Callback2 need std::string, etc.
Proposed solution should restrain from using std::function<> or virtual function, because the performance is a major concern here.
Thank.
Pass data through a void pointer is a good C solution but (IMHO) not a C++ (specially: not a C++11/c++14/C++17, with auto and std::tuple) good one.
So I suggest to return a value from callbackBegin() and pass the value as first argument to `callbackEnd(); something like
auto r = static_cast<Derived*>(this)->callbackBegin(s);
static_cast<Derived*>(this)->callbackEnd(r, s);
Observe (C++11 and newer magic) that using auto as type of the value returned by callbackBegin(), you can return different types from different `callbackBegin().
Bonus suggestion: be more generic in MyArray::push_back(): using variadic templates, there is no need of fix the number and the types of arguments received by callbackBack() and callbackEnd().
Using variadic templates you can modify push_back() as follows
template <typename ... Args>
void push_back (Args const & ... args)
{
auto r = static_cast<Derived*>(this)->callbackBegin(args...);
static_cast<Derived*>(this)->callbackEnd(r, args...);
}
The following is a full working example with two different callback classes (with different number of arguments and different return types)
#include <tuple>
#include <iostream>
template <typename derT>
struct myA
{
template <typename ... Args>
void push_back (Args const & ... args)
{
auto r = static_cast<derT*>(this)->callbackBegin(args...);
static_cast<derT*>(this)->callbackEnd(r, args...);
}
};
struct cb1 : public myA<cb1>
{
int callbackBegin (int s)
{ std::cout << "cb1 b" << std::endl; return s+5; }
void callbackEnd (int r, int s)
{ std::cout << "cb1 e -" << r << ", " << s << std::endl; }
};
struct cb2 : public myA<cb2>
{
std::tuple<std::string, int> callbackBegin (std::string const & name,
int num)
{ std::cout << "cb2 b" << std::endl; return {name+";", num+1}; }
void callbackEnd (std::tuple<std::string, int> const &,
std::string const & name, int num)
{ std::cout << "cb2 e -" << name << ", " << num << std::endl; }
};
int main ()
{
cb1 c1;
c1.push_back(5);
cb2 c2;
c2.push_back("string arg", 7);
return 0;
}
std::any would allow you to hold clock_t (or any other) object and do away with the void* pointers, however that's a C++17 concept and not yet widely available (although there are implementations such as boost::any).
In the meantime, your code may benefit from a little composition over inheritance, as array and callback are conceptually pretty different and don't seem to belong in the same inheritance hierarchy. So, preferring composition, the code might look something like:
template<class T> struct ICallback
{
virtual void callbackBegin(int s, std::unique_ptr<T>& p) = 0;
virtual void callbackEnd(int s, std::unique_ptr<T>& p) = 0;
};
template<class T> class MyArray
{
public:
MyArray(std::shared_ptr<ICallback<T>> cb) { callback = cb; }
void push_back(int s)
{
callback->callbackBegin(s, usrDataPtr);
//do something about array
callback->callbackEnd(s, usrDataPtr);
}
protected:
std::shared_ptr<ICallback<T>> callback;
std::unique_ptr<T> usrDataPtr;
};
class ClockCallback : public ICallback<clock_t>
{
public:
void callbackBegin(int s, std::unique_ptr<clock_t>& c){
c = std::make_unique<clock_t>(clock());
std::cout << "callbackBegin" << std::endl;
}
void callbackEnd(int s, std::unique_ptr<clock_t>& c){
clock_t clock2 = clock();
clock_t different = clock2 - (*c);
std::cout << "callbackEnd time(second)="
<< ((float)different) / CLOCKS_PER_SEC << std::endl;
}
};
int main() {
std::shared_ptr<ClockCallback> c = std::make_shared<ClockCallback>();
MyArray<clock_t> ma(c);
ma.push_back(7);
return 0;
}
You can use a smart pointer to avoid manually deleting your userData
std::unique_ptr<clock_t> userData;
pass it as a reference to your callbacks
void callbackBegin(int s, std::unique_ptr<clock_t> &userData)
and initialize it this way
userData = std::make_unique<clock_t>(clock())
The C++ magic you're asking about is a known as a virtual method. Virtual method is one of the C++ native ways to implement the callback:
class MyArray{
public:
void push_back(int s) {
const auto userData = callbackBegin(s); //# beautiful
//do something about array
callbackEnd(s, userData); //# beautiful
}
private:
virtual clock_t callbackBegin(int) const = 0;
virtual void callbackEnd(int, const clock_t&) const = 0;
};
class Callback : public MyArray{
clock_t callbackBegin(int s) const final {
std::cout<<"callbackBegin"<<std::endl;
return clock(); //# safe
}
void callbackEnd(int s,const clock_t& userData) const final { //#
const auto different = clock() - userDataTyped;
std::cout << "callbackEnd time(second)=";
std::cout << different/CLOCKS_PER_SEC << std::endl;
//# safe
}
};
Another way is to pass two callable objects to the MyArray ctor and using those objects in the push_back method. The callable objects shall store calls to the relevant class Callback methods. Use std::function to implement those callable objects.
I am trying to implement a simple dependency solver using std::future and std::async. Currenty I fail to understand is it even possible to do this. Question is, can we pass (not yet available) future to async call? If not, what actually can be done to have a chain of functions with some not yet ready input calling each other? Maybe, it is possible to override value passed to deferred async?
Probably my description is incomprehensible, so here is an example:
#include <iostream>
#include <future>
#include <map>
using namespace std;
int adder(future<int> a, future<int> b) {
return a.get() + b.get();
}
int main() {
map<char, future<int>> scheme;
scheme['c'] = future<int>(async(launch::deferred, [] { return 1;}));
scheme['a'] = future<int>(async(launch::deferred, adder, move(scheme['b']), move(scheme['c'])));
scheme['b'] = future<int>(async(launch::deferred, [] { return 3;}));
cout << scheme['a'].get() << endl;
}
We should have a scheme like this:
c
\
a ----- result
/
b
And a result of 4.
This code fails: move just takes an empty future and pass it to adder. If we swap lines with 'a' and 'b' it will work fine, but this way we already should know dependencies.
Use promises. And maybe future futures.
template<class T>
struct problem {
std::promise<std::shared_future<T>> p;
std::shared_future<std::shared_future<T>> f;
problem():f(p.get_future()){}
template<class W, class...Args>
void set(W&&work, Args&&...args){
p.set_value(std::async(std::launch::deferred, std::forward<W>(work), std::forward<Args>(args)...));
}
T get(){
return f.get().get();
}
};
int adder(problem<int>& a, problem<int>& b) {
return a.get() + b.get();
}
int main() {
std::map<char, problem<int>> scheme;
scheme['c'].set([] { return 1;} );
scheme['a'].set(adder, std::ref(scheme['b']), std::ref(scheme['c']));
scheme['b'].set([] { return 3;} );
std::cout << scheme['a'].get() << '\n';
}
There are probably easier ways.
live example.
I have 100 or so trampoline functions. I would like to know whether it is possible to automate wrapping each one inside a try/catch block.
Please be warned in advance, this is not an easy question. I will start by describing the problem with (simplified) code, and will then attempt to answer it as best I can below, so the reader may see where I am at.
Foo has a function pointer table:
EDIT: This is a C function pointer table. So it could accept static W::w.
Signatures are here: http://svn.python.org/projects/python/trunk/Include/object.h
EDIT: I've attempted a test case here:
class Foo {
Table table;
Foo() {
// Each slot has a default lambda.
:
table->fp_53 = [](S s, A a, B b) -> int {cout<<"load me!";};
table->fp_54 = [](S s, C c, D d, E e) -> float {cout<<"load me!";};
// ^ Note: slots MAY have different signatures
// only the first parameter 'S s' is guaranteed
}
// Foo also has a method for loading a particular slot:
:
void load53() { table->fp_53 = func53; }
void load54() { table->fp_54 = func54; }
:
}
If a particular slot is 'loaded', this is what gets loaded into it:
int func53(S s, A a, B b) {
try{
return get_base(s)->f53(a,b);
}
catch(...) { return 42;}
}
float func54(S s, C c, D d, E e) {
try{
return get_base(s)->f54(c,d,e);
}
catch(...) { return 3.14;}
}
I am trying to accomplish this using lambdas, so as to bypass having to define all of these func53 separately. Something like this:
class Foo {
:
void load53() {
table->fp_53 =
[](S s, A a, B b)->int { return get_base(s)->f53(a,b); }
}
void load54() {
table->fp_54 =
[](S s, C c, D d, E e)->float { return get_base(s)->f54(c,d,e); }
}
However, this is failing to trap errors. I need to be putting a try/catch around the return statement:
try{ return get_base(s)->f53(a,b); } catch{ return 42; }
However, this creates a lot of clutter. It would be nice if I could do:
return trap( get_base(s)->f53(a,b); )
My question is: is there any way to write this trap function (without using #define)?
This is what I've come up with so far:
I think this would pass all the necessary information:
trap<int, &Base::f53>(s,a,b)
trap's definition could then look like this:
template<typename RET, Base::Func>
static RET
trap(S s, ...) {
try {
return get_base(s)->Func(...);
}
catch {
return std::is_integral<RET>::value ? (RET)(42) : (RET)(3.14);
}
}
This may allow for a very clean syntax:
class Foo {
:
void load53() { table->fp_53 = &trap<int, &Base::f53>; }
void load54() { table->fp_54 = &trap<float, &Base::f54>; }
}
At this point I'm not even sure whether some laws have been violated. table->fp_53 must be a valid C function pointer.
Passing in the address of a nonstatic member function (&Base::f53>) won't violate this, as it is a template parameter, and is not affecting the signature for trap
Similarly, ... should be okay as C allows varargs.
So if this is indeed valid, can it be cleaned up?
My thoughts are:
1) maybe the ... should be moved back to the template parameter as a pack.
2) maybe it is possible to deduce the return type for trap, and save one template parameter
3) that Base::Func template parameter is illegal syntax. And I suspect it isn't even close to something legal. Which might scupper the whole approach.
#include <utility>
template <typename T, T t>
struct trap;
template <typename R, typename... Args, R(Base::*t)(Args...)>
struct trap<R(Base::*)(Args...), t>
{
static R call(int s, Args... args)
{
try
{
return (get_base(s)->*t)(std::forward<Args>(args)...);
}
catch (...)
{
return std::is_integral<R>::value ? static_cast<R>(42)
: static_cast<R>(3.14);
}
}
};
Usage:
table->fp_53 = &trap<decltype(&Base::f53), &Base::f53>::call;
table->fp_54 = &trap<decltype(&Base::f54), &Base::f54>::call;
DEMO
Note: std::forward can still be used although Args is not a forwarding reference itself.
template<typename RET, typename... Args>
struct trap_base {
template<RET (Base::* mfptr)(Args...)>
static RET
trap(S s, Args... args) {
try {
return (get_base(s).*mfptr)(args...);
}
catch (...) {
return std::is_integral<RET>::value ? (RET)(42) : (RET)(3.14);
}
}
};
Usage:
void load53() { table.fp_53 = &trap_base<int, int>::trap<&Base::f53>; }
void load54() { table.fp_54 = &trap_base<float, int, float>::trap<&Base::f54>; }
Demo.
You can probably also use a partial specialization to extract RET and Args from decltype(&base::f53) etc.
trap_gen is a function that returns a function pointer to a function generated on the fly, the equivalent of your trap function.
Here is how you use it
table->fp_53 = trap_gen<>(Base::f53);
table->fp_54 = trap_gen<>(Base::f54);
...
Where Base::f53 and Base::f54 are static member functions (or function pointers, or global functions in a namespace).
Proof of concept :
#include <iostream>
template<typename R, class...A>
R (*trap_gen(R(*f)(A...)))(A...)
{
static auto g = f;
return [](A... a)
{
try {
return g(a...);
} catch (...) {
return std::is_integral<R>::value ? static_cast<R>(42)
: static_cast<R>(3.14);
}
};
}
int add(int a, int b)
{
return a+b;
}
int main() {
int(*f)(int, int) = trap_gen<>(add);
std::cout << f(2, 3) << std::endl;
return 0;
}
How can I write a wrapper that can wrap any function and can be called just like the function itself?
The reason I need this: I want a Timer object that can wrap a function and behave just like the function itself, plus it logs the accumulated time of all its calls.
The scenario would look like this:
// a function whose runtime should be logged
double foo(int x) {
// do something that takes some time ...
}
Timer timed_foo(&foo); // timed_foo is a wrapping fct obj
double a = timed_foo(3);
double b = timed_foo(2);
double c = timed_foo(5);
std::cout << "Elapsed: " << timed_foo.GetElapsedTime();
How can I write this Timer class?
I am trying something like this:
#include <tr1/functional>
using std::tr1::function;
template<class Function>
class Timer {
public:
Timer(Function& fct)
: fct_(fct) {}
??? operator()(???){
// call the fct_,
// measure runtime and add to elapsed_time_
}
long GetElapsedTime() { return elapsed_time_; }
private:
Function& fct_;
long elapsed_time_;
};
int main(int argc, char** argv){
typedef function<double(int)> MyFct;
MyFct fct = &foo;
Timer<MyFct> timed_foo(fct);
double a = timed_foo(3);
double b = timed_foo(2);
double c = timed_foo(5);
std::cout << "Elapsed: " << timed_foo.GetElapsedTime();
}
(BTW, I know of gprof and other tools for profiling runtime, but having such a Timer object to log the runtime of a few selected functions is more convenient for my purposes.)
Basically, what you want to do is impossible in current C++. For any number of arity of function you want to wrap, you need to overload by
const reference
non-const reference
But then it's still not perfectly forwarding (some edge cases still stand), but it should work reasonable well. If you limit yourself to const references, you can go with this one (not tested):
template<class Function>
class Timer {
typedef typename boost::function_types
::result_type<Function>::type return_type;
public:
Timer(Function fct)
: fct_(fct) {}
// macro generating one overload
#define FN(Z, N, D) \
BOOST_PP_EXPR_IF(N, template<BOOST_PP_ENUM_PARAMS(N, typename T)>) \
return_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& t)) { \
/* some stuff here */ \
fct_(ENUM_PARAMS(N, t)); \
}
// generate overloads for up to 10 parameters
BOOST_PP_REPEAT(10, FN, ~)
#undef FN
long GetElapsedTime() { return elapsed_time_; }
private:
// void() -> void(*)()
typename boost::decay<Function>::type fct_;
long elapsed_time_;
};
Note that for the return type, you can use boost's function types library. Then
Timer<void(int)> t(&foo);
t(10);
You can also overload using pure value parameters, and then if you want to pass something by reference, use boost::ref. That's actually a pretty common technique, especially when such parameters are going to be saved (this technique is also used for boost::bind):
// if you want to have reference parameters:
void bar(int &i) { i = 10; }
Timer<void(int&)> f(&bar);
int a;
f(boost::ref(a));
assert(a == 10);
Or you can go and add those overloads for both const and non-const versions as explained above. Look into Boost.Preprocessor for how to write the proper macros.
You should be aware that the whole thing will become more difficult if you want to be able to pass arbitrary callables (not only functions), since you will need a way then to get their result type (that's not all that easy). C++1x will make this sort of stuff way easier.
Here is an easy way to wrap functions.
template<typename T>
class Functor {
T f;
public:
Functor(T t){
f = t;
}
T& operator()(){
return f;
}
};
int add(int a, int b)
{
return a+b;
}
void testing()
{
Functor<int (*)(int, int)> f(add);
cout << f()(2,3);
}
I assume you need this for test purpose and aren't going to use them as a real proxies or decorators. So you won't need to use operator() and can use any other more-less convenient method of call.
template <typename TFunction>
class TimerWrapper
{
public:
TimerWrapper(TFunction function, clock_t& elapsedTime):
call(function),
startTime_(::clock()),
elapsedTime_(elapsedTime)
{
}
~TimerWrapper()
{
const clock_t endTime_ = ::clock();
const clock_t diff = (endTime_ - startTime_);
elapsedTime_ += diff;
}
TFunction call;
private:
const clock_t startTime_;
clock_t& elapsedTime_;
};
template <typename TFunction>
TimerWrapper<TFunction> test_time(TFunction function, clock_t& elapsedTime)
{
return TimerWrapper<TFunction>(function, elapsedTime);
}
So to test some of yours function you should use only test_time function and not the direct TimerWrapper structure
int test1()
{
std::cout << "test1\n";
return 0;
}
void test2(int parameter)
{
std::cout << "test2 with parameter " << parameter << "\n";
}
int main()
{
clock_t elapsedTime = 0;
test_time(test1, elapsedTime).call();
test_time(test2, elapsedTime).call(20);
double result = test_time(sqrt, elapsedTime).call(9.0);
std::cout << "result = " << result << std::endl;
std::cout << elapsedTime << std::endl;
return 0;
}
You may probably find an answer if you look at the implementation of std::tr1::function that you include.
In c++11, std:: function is implemented with variadic templates. Using such templates your timer class can look like
template<typename>
class Timer;
template<typename R, typename... T>
class Timer<R(T...)>
{
typedef R (*function_type)(T...);
function_type function;
public:
Timer(function_type f)
{
function = f;
}
R operator() (T&&... a)
{
// timer starts here
R r = function(std::forward<T>(a)...);
// timer ends here
return r;
}
};
float some_function(int x, double y)
{
return static_cast<float>( static_cast<double>(x) * y );
}
Timer<float(int,double)> timed_function(some_function); // create a timed function
float r = timed_function(3,6.0); // call the timed function
Stroustrup had demonstrated a function wrapper(injaction) skill with overloading the operator->. The key idea is: operator-> will repeatly called until it meets a native pointer type, so let Timer::operator-> return a temp object, and the temp object return its pointer. Then following will happen:
temp obj created (ctor called).
target function called.
temp obj destructed (dtor called).
And you can inject any code within the ctor and the dtor. Like this.
template < class F >
class Holder {
public:
Holder (F v) : f(v) { std::cout << "Start!" << std::endl ; }
~Holder () { std::cout << "Stop!" << std::endl ; }
Holder* operator->() { return this ; }
F f ;
} ;
template < class F >
class Timer {
public:
Timer ( F v ) : f(v) {}
Holder<F> operator->() { Holder<F> h(f) ; return h ; }
F f ;
} ;
int foo ( int a, int b ) { std::cout << "foo()" << std::endl ; }
int main ()
{
Timer<int(*)(int,int)> timer(foo) ;
timer->f(1,2) ;
}
The implementation and the usage are both easy.
A solution using macros and templates: For example you want to wrap
double foo( double i ) { printf("foo %f\n",i); return i; }
double r = WRAP( foo( 10.1 ) );
Before and after calling foo() the wrapper functions beginWrap() and endWrap() should be called. (With endWrap() being a template function.)
void beginWrap() { printf("beginWrap()\n"); }
template <class T> T endWrap(const T& t) { printf("endWrap()\n"); return t; }
The macro
#define WRAP(f) endWrap( (beginWrap(), f) );
uses the precedence of the comma-operator to assure beginWrap() is called first. The result of f is passed to endWrap() which just returns it.
So the output is:
beginWrap()
foo 10.100000
endWrap()
And the result r contains 10.1.
You're out for a big challenge if you are looking to create a generic class that can wrap and call an arbitrary function. In this case you'd have to make the functor (the operator()) to return double and take an int as a parameter. Then you have created a family of classes that can call all functions with that same signature. As soon as you want to add more types of functions, you need more functors of that signature, e.g.
MyClass goo(double a, double b)
{
// ..
}
template<class Function>
class Timer {
public:
Timer(Function& fct)
: fct_(fct) {}
MyClass operator()(double a, double b){
}
};
EDIT: Some spelling errors
It's not really clear to me for what you are looking.. However, for the given example, it's simply:
void operator() (int x)
{
clock_t start_time = ::clock(); // time before calling
fct_(x); // call function
clock_t end_time = ::clock(); // time when done
elapsed_time_ += (end_time - start_time) / CLOCKS_PER_SEC;
}
Note: This will measure the time in seconds. If you want to have high-precision timers, you probably have to check OS specific functionality (like GetTickCount or QueryPerformanceCounter on Windows).
If you want to have a generic function wrapper, you should have a look on Boost.Bind that will help tremendeously.
If your compiler supports variadic macros, I'd try this:
class Timer {
Timer();// when created notes start time
~ Timer();// when destroyed notes end time, computes elapsed time
}
#define TIME_MACRO(fn, ...) { Timer t; fn(_VA_ARGS_); }
So, to use it, you'd do this:
void test_me(int a, float b);
TIME_MACRO(test_me(a,b));
That's off the cuff, and you'd need to play around to get return types to work (I think you'd have to add a type name to the TIME_MACRO call and then have it generate a temp variable).
Here's how I'd do it, using a function pointer instead of a template:
// pointer to a function of the form: double foo(int x);
typedef double (*MyFunc) (int);
// your function
double foo (int x) {
// do something
return 1.5 * x;
}
class Timer {
public:
Timer (MyFunc ptr)
: m_ptr (ptr)
{ }
double operator() (int x) {
return m_ptr (x);
}
private:
MyFunc m_ptr;
};
I changed it to not take a reference to the function, but just a plain function pointer. Usage remains the same:
Timer t(&foo);
// call function directly
foo(i);
// call it through the wrapper
t(i);
In C++ functions are first class citizens, you can literally pass a function as a value.
Since you want it to take an int and return a double:
Timer(double (*pt2Function)(int input)) {...