I want to add some code before every function call to do some checking. The only way I know is:
#define SOME_CODE printf(\"doing something...\");
class test
Depending on what you're hoping to achieve as a result of this you can sort of make something (easily enough for free functions or static member functions) in C++ with functor objects which wrap real calls, e.g.:
#include
template
struct Wrap {
void operator()() const {
std::cout << "Pre call hook" << std::endl;
f();
}
};
namespace {
void test_func() {
std::cout << "Real function" << std::endl;
}
}
const Wrap<&test_func> wrapped_test_func = {};
int main() {
wrapped_test_func();
return 0;
}
Clearly this needs some more work to be generic enough e.g. C++0x variadic templates or lots of overloads. Making it work nicely with member functions is also more fiddly.
I've sketched an outline for a (non-intrusive) way of doing this for member functions too:
#include
template
class WrapMem {
C& inst;
public:
WrapMem(C& inst) : inst(inst) {}
void operator()() {
std::cout << "Pre (method) call hook" << std::endl;
((inst).*(F))();
}
void operator()() const {
std::cout << "Pre (method, const) call hook" << std::endl;
((inst).*(F))();
}
};
class Foo {
public:
void method() { std::cout << "Method called" << std::endl; }
void otherstuff() {}
};
class FooWrapped : private Foo {
public:
FooWrapped() : method(*this) {}
using Foo::otherstuff;
WrapMem method;
};
int main() {
FooWrapped f;
f.otherstuff();
f.method();
return 0;
}
You could also skip the private inheritance and using
to expose non-wrapped methods, but you need to be careful about destructors and it's easy to accidentally bypass if you do that. (e.g. implicit cast for reference to base). The non-intrusive way is also limited to only working for the public interface and not for internal calls either.
With C++11 you can get perfect forwarding and also reduce the construction of the wrapping objects to a simple macro that takes the class and member function name and deduces the rest for you, e.g.:
#include
#include
template
struct Wrapper {
template
class MemberFn {
C& inst;
public:
MemberFn(C& inst) : inst(inst) {}
MemberFn& operator=(const MemberFn&) = delete;
Ret operator()(Args&& ...args) {
return ((inst).*(F))(std::forward(args)...);
}
Ret operator()(Args&& ...args) const {
return ((inst).*(F))(std::forward(args)...);
}
};
};
template
struct deduce_memfn;
template
struct deduce_memfn {
template
static typename Wrapper::template MemberFn make();
};
template
decltype(deduce_memfn()) deduce(T);
template
struct workaround : T {}; // Clang 3.0 doesn't let me write decltype(deduce(&Class::Method))::make...
#define WRAP_MEMBER_FN(Class, Method) decltype(workaround::make<&Class::Method>()) Method = *this
class Foo {
public:
Foo(int);
double method(int& v) { return -(v -= 100) * 10.2; }
void otherstuff();
};
class WrappedFoo : private Foo {
public:
using Foo::Foo; // Delegate the constructor (C++11)
WRAP_MEMBER_FN(Foo, method);
using Foo::otherstuff;
};
int main() {
WrappedFoo f(0);
int i = 101;
std::cout << f.method(i) << "\n";
std::cout << i << "\n";
}
(Note: this deduction won't work with overloads) This was tested with Clang 3.0.