Using Lambda/Template/SFINAE to automate try/catch-safeguarding of trampoline functions - c++

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

Related

Creating an object of specific type based on user input

We have
enum Enum {A,B,C,D,E,F,G,H, NumEnums};
class Base {};
template <Enum...> class Thing : public Base {};
and the function
Base* create (std::list<Enum>& input);
is to create an object of the type that corresponds to input. For example,
if input = {A,E,C,G,D};, then the output shall be of type Thing<A,E,C,G,D>* (let's forget the sorting here). Now I know input is obtained during run-time, but by doing a search, the output can be obtained fairly quickly. If Thing had only one parameter (i.e. input has size() one), then the simple
template <int N>
Base* createHelper (const std::list<Enum>& input) {
const Enum En = static_cast<Enum>(N);
if (input.front() == En)
return new Thing<En>;
return createHelper<N+1>(input);
}
template <>
Base* createHelper<NumEnums> (const std::list<Enum>&) {
return nullptr;
}
Base* create (const std::list<Enum>& input) {
return createHelper<0>(input);
}
will do. I tried to generalize the above to any size list (the size would have to be determined during run-time through a similar recursion as above, but that should be fairly quick too). But I got totally lost on how. So I tried to examine the structure of the naïve method:
#include <iostream>
#include <list>
#include <type_traits>
#include <typeinfo>
enum Enum {A,B,C,D,E,F,G,H, NumEnums};
class Base {
public:
virtual void print() const = 0;
};
template <Enum...> class Thing : public Base {
virtual void print() const override {std::cout << typeid(*this).name() << '\n';}
};
Base* create (std::list<Enum>& input) {
if (input.front() == A) {
input.pop_front();
if (input.empty())
return new Thing<A>;
else {
if (input.front() == A) {
input.pop_front();
if (input.empty())
return new Thing<A,A>;
else {
// ....
}
}
else if (input.front() == B) {
input.pop_front();
if (input.empty())
return new Thing<A,B>;
else {
// ....
}
}
}
}
else if (input.front() == B) {
// similar
}
// ...
}
int main() {
std::list<Enum> userInput = {A,B};
// Wish to construct an instance of Thing<A,B> (efficiently).
Base* thing = create(userInput);
thing->print(); // Thing<A,B>
}
I figured I could put this in recursive form. But I cannot think of it. I know the one-dimensional case can be generalized, but I need help here. Or perhaps there is a better way to do it altogether? Once it works, it should not take anymore than a fraction of a second for the create function to return, assuming NumEnums is a decent size and the Thing class has just several template arguments, and not hundreds.
Edit: Turns out, there may be a viable solution here:
Create an associate array between your key and a type factory class.
Dynamically allocate any variables you may need from the type factory once you have it selected (preferably using std::unique_ptr).
The end result may end of looking like this:
std::unordered_map<std::string, type_allocator> str_to_type;
str_to_type["a"] = type_allocator(int); //where type_allocator derives the type of the class from the input variable.
auto variable = str_to_type[input].allocate();
For specific size, if you compute a single index, you may dispatch at runtime to the correct compile time function:
template <std::size_t N>
std::unique_ptr<Base> make_thing3()
{
constexpr Enum a2 = Enum(N % NumEnums);
constexpr Enum a1 = Enum((N / NumEnums) % NumEnums);
constexpr Enum a0 = Enum((N / NumEnums / NumEnums) % NumEnums);
return std::make_unique<Thing<a0, a1, a2>>();
}
template <std::size_t... Is>
std::unique_ptr<Base> make_thing3(std::size_t index, std::index_sequence<Is...>)
{
using maker = std::unique_ptr<Base>();
maker* fs[] = {&make_thing3<Is>...};
return fs[index]();
}
std::unique_ptr<Base> make_thing3(const std::array<Enum, 3u>& a)
{
std::size_t index = 0;
for (Enum e : a) {
index *= NumEnums;
index += e;
}
constexpr std::size_t total = NumEnums * NumEnums * NumEnums;
return make_thing3(index, std::make_index_sequence<total>{});
}
Live Demo
Note: I had to change size of Enum, and reduce my example from make_thing5 to make_thing3 due to compiler limit (not sure if it came from the site or if it is true limits)
This solution shows that though the compile-time is long (due to the many template instantiations), the run-time look-up is instant. The compiler limits is 3 enum values as input though. The empty input case is handled too (the return type being Thing<>*).
#include <iostream>
#include <list>
#define show(variable) std::cout << #variable << " = " << variable << std::endl;
enum Enum {A,B,C,D,E,F,G,H, NumEnums};
class Base {
public:
virtual void print() const = 0;
};
template <Enum... Es> class Thing : public Base {
virtual void print() const override {
const std::list<int> a = {((std::cout << Es << ' '), 0)...};
std::cout << "\nPack size = " << sizeof...(Es) << '\n';
}
};
template <int N, int Size, Enum... Es>
struct Create {
static Base* execute (std::list<Enum>& input) {
const Enum En = static_cast<Enum>(N);
if (input.front() == En) {
input.pop_front();
return Create<0, Size-1, Es..., En>::execute(input);
}
return Create<N+1, Size, Es...>::execute(input);
}
};
template <int N, Enum... Es>
struct Create<N, 0, Es...> {
static Base* execute (std::list<Enum>&) {return new Thing<Es...>;}
};
template <int Size, Enum... Es>
struct Create<NumEnums, Size, Es...> {
static Base* execute (std::list<Enum>&) {return nullptr;} // This will never be reached
};
template <int Size>
Base* do_create (std::list<Enum>& input) {
if (input.size() == Size)
return Create<0, Size>::execute(input);
return do_create<Size+1>(input);
}
template <>
Base* do_create<4> (std::list<Enum>&) {
std::cout << "Cannot exceed 3 values.\n";
return nullptr;
}
Base* create (std::list<Enum>& input) {
return do_create<0>(input);
}
int main() {
std::list<Enum> input = {E,A,F};
Base* thing = create(input);
thing->print(); // 4 0 5
input = {};
create(input)->print(); // Pack size = 0.
}

Abstract Factory Improvements

Edited: I decided to edit this post for future readers. Put simply, it shows an acceptable way to call constructors of template types within the template list. For example, the following:
int main()
{
unique_ptr<factory> real_widget_factory(new widget_factory(5.0, 6.0));
}
Instead of just being limited to:
unique_ptr<factory> real_widget_factory(new widget_factory()); // empty
The Standard provides all the necessary infrastructure you need. You can delete all of that code.
template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(std::forward<Args>(args)...);
}
struct train_factory {
train_factory(std::function<std::unique_ptr<locomotive>()> ml,
std::function<std::unique_ptr<freight_car>()> mc)
: make_locomotive(std::move(ml)),
, make_car(std::move(mc)) {}
std::function<std::unique_ptr<locomotive>()> make_locomotive;
std::function<std::unique_ptr<freight_car>()> make_car;
};
train_factory make_concrete_factory(double x1, double x2) {
return train_factory(
[=] { return make_unique<real_locomotive>(x1); },
[=] { return make_unique<real_car>(x2); }
);
}
int main() {
auto fact = make_concrete_factory(1.0);
auto loc = fact.make_locomotive();
}
This appears to meet all of your requirements. In this case, the functions have the arguments to the factory bound in (and this binding is arbitrary). You can of course also modify the functions to take the arguments if you like, or use both in arbitrary ways and combinations.
struct train_factory {
std::function<std::unique_ptr<locomotive>(double)> make_locomotive;
std::function<std::unique_ptr<freight_car>(double)> make_car;
};
train_factory make_concrete_factory() {
return train_factory {
[](double x1) { return make_unique<real_locomotive>(x1); },
[](double x2) { return make_unique<real_car>(x2); }
};
}
int main() {
auto fact = make_concrete_factory();
auto loc = fact.make_locomotive(1.0);
}

Creating Task Then function(like std::future.then)

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

c++11 : Compare lambda expression

Imagine have the following class :
#include <functional>
#include <vector>
template<typename T1> class Signaler
{
public:
typedef std::function<void (T1)> Func;
public:
Signaler()
{
}
void Call(T1 arg)
{
for(Int32 i = (Int32)_handlers.size() - 1; i > -1; i--)
{
Func handler = _handlers[i];
handler(arg);
}
}
Signaler& operator+=(Func f)
{
_handlers.push_back( f );
return *this;
}
Signaler& operator-=(Func f)
{
for(auto i = _handlers.begin(); i != _handlers.end(); i++)
{
if ( (*i).template target<void (T1)>() == f.template target<void (T1)>() )
{
_handlers.erase( i );
break;
}
}
return *this;
}
private:
std::vector<Func> _handlers;
};
And I use it the following way :
Signaler Global::Signal_SelectionChanged;
class C1
{
public:
void Register()
{
Global::Signal_SelectionChanged += [&](SelectionChangedEventArgs* e) { this->selectionChangedEvent_cb(e); };
}
void Unregister()
{
Global::Signal_SelectionChanged -= [&](SelectionChangedEventArgs* e) { this->selectionChangedEvent_cb(e); };
}
void selectionChangedEvent_cb(SelectionChangedEventArgs* e) {}
};
class C2
{
public:
void Register()
{
Global::Signal_SelectionChanged += [&](SelectionChangedEventArgs* e) { this->selectionChangedEvent_cb(e); };
}
void Unregister()
{
Global::Signal_SelectionChanged -= [&](SelectionChangedEventArgs* e) { this->selectionChangedEvent_cb(e); };
}
void selectionChangedEvent_cb(SelectionChangedEventArgs* e) {}
};
Now, the problem that I have is when I call 'Unregister' from the class C2, it removes the wrong version of the 'lambda" expression, because the 'lambda' looks similar.
How can I solve this problem ?
Any idea ?
Thanks
The problem is that you are using std::function::target with a type that is not the type of the object stored in the std::function, so it is returning a null pointer. That is, you need to know the actual type of the object stored in the std::function to be able to call target.
Even if you were to call target with the lambda closure type used to add the callback, this wouldn't work for two reasons: first, lambda closure types are unique (5.1.2p3) so the += and -= lambdas have different types even if they are syntactically identical; second, the closure type for a lambda-expression is not defined to have an operator== (5.1.2p3-6, 19-20), so your code would not even compile.
Switching from lambdas to std::bind wouldn't help, as bind types are also not defined to have operator==.
Instead, consider using an id to register/unregister callbacks. You could also use your own functor which defines operator==, but that would be a lot of work.

C++: Function wrapper that behaves just like the function itself

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)) {...