I am writing a library for thread management using C++ for my app and as part of the same I am trying to write a template class that takes a FunctionPointer to be executed inside the run function. I am a Java developer and trying to visualize as follows:
class MyRunnable : public Runnable {
public:
MyRunnable(fp)
{
mFp = fp;
}
private:
FunctionPointer mFp;
// Will be called by the thread pool using a thread
void run()
{
mFp();
}
}
class ThreadManager {
public:
void execute(MyRunnable runnable) {
executeOnAThreadPool(runnable);
}
}
Since I am not fluent with C++ syntax, I am finding hard to get the constructor defined to take a FunctionPointer as argument with variable number of arguments for the FunctionPointer. Something like:
MyRunnable(Fp fp, Args... args)
Can someone please help me defining the constructor for MyRunnable class above.
Thanks.
Not sure... but seems to me that you're looking something as
class MyRunnable
{
private:
std::function<void()> mF;
public:
template <typename F, typename ... Args>
MyRunnable (F && f, Args && ... args)
: mF{ [&f, &args...](){ std::forward<F>(f)(std::forward<Args>(args)...); } }
{ }
void run ()
{ mF(); }
};
The following is a full compiling example
#include <iostream>
#include <functional>
class MyRunnable
{
private:
std::function<void()> mF;
public:
template <typename F, typename ... Args>
MyRunnable (F && f, Args && ... args)
: mF{ [&f, &args...](){ std::forward<F>(f)(std::forward<Args>(args)...); } }
{ }
void run ()
{ mF(); }
};
void foo (int a, long b, std::string const & c)
{ std::cout << "executing foo() with " << a << ", " << b << ", " << c << '\n'; }
int main ()
{
MyRunnable mr{foo, 1, 2l, "three"};
std::cout << "before run" << '\n';
mr.run();
}
that prints
before run
executing foo() with 1, 2, three
Related
I'm trying to write external draw call optimization, and for that I need to collect hooked calls, store their arguments to analyze them later on.
I've been able to make deferred calls, and somewhat readable arguments, stored in tuple, but I need to read arguments from base class and after thorough googling I can't find anything applicable.
I'll work with array of IDelegateBase mostly, and it would be very inconvenient to convert them to Delegate<...> with full signature, when I mostly would read just one argument. Therefore, I need virtual templated method in IDelegateBase, which would return n-th argument. But virtual templated methods are impossible, so probably I'd have to have templated method in base class, which would call non-template (boost::any?) virtual method and cast it's result, I suppose. But, anyway, I can't get n-th element from tuple via runtime variable.
#include <functional>
#include <iostream>
class IDelegateBase
{
public:
virtual void invoke() { }
};
template <typename T, typename... Args>
class Delegate : public IDelegateBase
{
private:
void (*_f)(Args...);
std::tuple<Args...> _args;
public:
Delegate(T& f, Args &...args)
: _f(f), _args(args...) { }
void invoke() final
{
std::apply(_f, _args);
}
};
void a() { std::cout << "a called;\n"; }
void b(int x) { std::cout << "b called with " << x << "\n"; }
void c(int x, float y) { std::cout << "c called with " << x << ", " << y << "\n"; }
int main()
{
IDelegateBase* d = new Delegate(a);
d->invoke();
int i = 42;
d = new Delegate(b, i);
d->invoke();
i = 21;
float f = 0.999;
d = new Delegate(c, i, f);
d->invoke();
// I need something like this:
auto test = d->getArgument<float>(1);
};
Update:
Final solution with kind of type checking: https://godbolt.org/z/xeEWTeosx
You could provide a virtual function returning void* and use it in a template, but type safety goes down the drain: Should you ever get the type wrong, you'll end up with undefined behaviour.
For getting element using an index you can use a recursive helper template that compares with one index per recursive call.
class IDelegateBase
{
public:
virtual void invoke() { }
template<class T>
T const& getArgument(size_t index) const
{
return *static_cast<T const*>(getArgumentHelper(index));
}
protected:
virtual void const* getArgumentHelper(size_t index) const = 0;
};
template <typename T, typename... Args>
class Delegate : public IDelegateBase
{
private:
void (*_f)(Args...);
std::tuple<Args...> _args;
public:
Delegate(T& f, Args &...args)
: _f(f), _args(args...) { }
void invoke() final
{
std::apply(_f, _args);
}
protected:
void const* getArgumentHelper(size_t index) const override
{
return GetHelper<0>(index, _args);
}
private:
template<size_t index>
static void const* GetHelper(size_t i, std::tuple<Args...> const& args)
{
if constexpr (sizeof...(Args) > index)
{
if (index == i)
{
return &std::get<index>(args);
}
else
{
return GetHelper<index + 1>(i, args);
}
}
else
{
throw std::runtime_error("index out of bounds");
}
}
};
The use of if constexpr is needed here, since std::get does not compile if a of tuple index out of bounds is used.
This question already has answers here:
Is it possible to give a definition of a class in C++ during allocation, as is allowed in java
(4 answers)
Closed 6 years ago.
Let's say I have the following callback class:
class LogCallback {
public:
virtual void sendLog(std::string log) = 0;
virtual void setErrorCode(int code) = 0;
};
And I have the engine which accepts a callback implementation:
class Engine {
public:
Engine();
virtual ~Engine();
void setCallback(LogCallback* callback);
void start();
private:
LogCallback* logCallback;
};
Now I can create an implementation class:
class OutLogger : public LogCallback {
void sendLog(std::string log) {
cout << "out: " << log << endl;
}
void setErrorCode(int code) {
sendLog("error code " + std::to_string(code));
}
};
And use it:
int process() {
Engine engine;
OutLogger out;
engine.setCallback(&out);
engine.start();
}
In C++11 I can also use an anonymous local class:
int anonymous() {
Engine engine;
class : public LogCallback {
void sendLog(std::string log) {
cerr << "err: " << log << endl;
}
void setErrorCode(int code) {
sendLog("error code " + std::to_string(code));
}
} err;
engine.setCallback(&err);
engine.start();
}
Now there is the question: can I do the same without the explicit anonymous class, inside the function call?
If it was Java I would do it like this:
public class AnonymousClass {
private abstract class LogCallback {
abstract void sendLog(String log);
abstract void setErrorCode(int code);
}
private class Engine {
public void setCallback(LogCallback callback) {
this.callback = callback;
}
public void start() {
if (callback != null) {
callback.sendLog("Starting...");
}
}
private LogCallback callback;
}
public void process() {
Engine engine = new Engine();
engine.setCallback(new LogCallback() {
#Override
void sendLog(String log) {
System.out.println("out: " + log);
}
#Override
void setErrorCode(int code) {
sendLog("error code " + code);
}
});
engine.start();
}
public static void main(String[] args) {
AnonymousClass example = new AnonymousClass();
example.process();
}
}
Holt's comment above is correct. The only way to declare a new type in an expression like Java's new X() { ... } is a lambda expression, and you can't make that derive from your abstract base class.
The C++ way to do it would be to stop all that OOP inheritance ickiness and use a function template, or a function taking a type erased std::function, so it accepts any callable with a suitable call signature, then you could use a lambda.
For example:
class Engine {
public:
enum class LogType { String, ErrorCode };
using LogCallback = std::function<void(LogType, std::string, int)>;
Engine();
virtual ~Engine();
void setCallback(LogCallback callback) { logCallback = callback; }
void start() {
if (logCallback)
logCallback(LogType::String, "Starting...", 0);
}
private:
LogCallback logCallback;
};
int anonymous() {
Engine engine;
engine.setCallback([](Engine::LogType t, std::string log, int code) {
if (t == Engine::LogType::ErrorCode)
log = "error code " + std::to_string(code);
cerr << "err: " << log << endl;
});
engine.start();
}
(A nicer definition for the LogCallback type would be:
using LogCallback = std::function<void(std::variant<std::string, int>)>;
but we don't have variant in C++ just yet.)
You cannot implement interface in place, but you can create generic class with call back functions as parameters:
class GenericLogCallback : public LogCallback {
public:
GenericLogCallback(std::function<void (std::string)> sendlog,
std::function<void (int)> seterrorcode) : sendLog_(std::move(sendlog)),
setErrorCode_(std::move(seterrorcode)) {}
virtual void sendLog(std::string log) override {
if(sendLog_) sendLog_(log);
}
virtual void setErrorCode(int code) override {
if(setErrorCode_) setErrorCode_(code);
}
private:
std::function<void (std::string)> sendLog_;
std::function<void (int)> setErrorCode_;
};
...
GenericLogCallback err([](std::string){},[](int){});
engine.setCallback(&err);
The answers already posted here using std::function are good, but if you care a lot about performance you can do one better by directly storing the functors (which could be results of std::bind(), or C-style function pointers, or lambdas):
template <typename SendLog, typename SetErrorCode>
class GenericLogger : public LogCallback {
public:
GenericLogger(SendLog sender, SetErrorCode setter)
: m_sender(sender), m_setter(setter) {}
void sendLog(std::string log) override {
m_sender(log);
}
void setErrorCode(int code) override {
m_setter(code);
}
SendLog m_sender;
SetErrorCode m_setter;
};
template <typename SendLog, typename SetErrorCode>
GenericLogger<SendLog, SetErrorCode> makeLogger(SendLog sender, SetErrorCode setter) {
return GenericLogger<SendLog, SetErrorCode>(sender, setter);
}
void sendLog(std::string log) {
std::cout << "out: " << log << std::endl;
}
void setErrorCode(int code) {
sendLog("error code " + std::to_string(code));
}
int main()
{
Engine engine;
auto out = makeLogger(
[](std::string s){std::cout << "lambda: " << s << '\n';},
setErrorCode);
engine.setCallback(&out);
engine.start();
}
The above avoids using std::function except when the actual arguments to makeLogger() are of that type. This reduces overhead by invoking exactly the given functor, rather than always storing a std::function.
One thing you could do is create a wrapper class that allows to use lambdas:
template<class F1, class F2>
struct LogCallbackF : LogCallback {
F1 f1;
F2 f2;
LogCallbackF(F1 f1, F2 f2) : f1(std::move(f1)), f2(std::move(f2)) {}
void sendLog(std::string msg) override { f1(msg); }
void setErrorCode(int code) override { f2(code); }
};
template<class F1, class F2>
inline LogCallbackF<F1, F2> make_log_callback(F1 f1, F2 f2) {
return {std::move(f1), std::move(f2)};
}
void process() {
Engine engine;
auto callback = make_log_callback(
[](std::string a) { std::cout << a << '\n'; },
[](int a) { std::cout << a << '\n'; }
);
engine.setCallback(&callback);
engine.start();
}
I am looking for a way to decorate functions or lambdas in C++. The goal is to do something before and after the function call. As I've seen the closest thing to use is std::function but it needs to have the types of its arguments.
class FunctionDecorator
{
public:
FunctionDecorator( std::function func )
: m_func( func )
void operator()()
{
// do some stuff prior to function call
m_func();
// do stuff after function call
}
private:
std::function m_func;
};
It would be great if by template type could be used in std::function and it could deduce it somehow when i pass pointer to a function or a result from std::bind.
Is such thing possible in C++.
Hmm. I may or may not have gone overkill.
#include <type_traits>
#include <utility>
#include <iostream>
template <class T>
struct RetWrapper {
template <class Tfunc, class... Targs>
RetWrapper(Tfunc &&func, Targs &&... args)
: val(std::forward<Tfunc>(func)(std::forward<Targs>(args)...)) {}
T &&value() { return static_cast<T &&>(val); }
private:
T val;
};
template <>
struct RetWrapper<void> {
template <class Tfunc, class... Targs>
RetWrapper(Tfunc &&func, Targs &&... args) {
std::forward<Tfunc>(func)(std::forward<Targs>(args)...);
}
void value() {}
};
template <class Tfunc, class Tbefore, class Tafter>
auto decorate(Tfunc &&func, Tbefore &&before, Tafter &&after) {
return [
func = std::forward<Tfunc>(func),
before = std::forward<Tbefore>(before),
after = std::forward<Tafter>(after)
] (auto &&... args) -> decltype(auto) {
before(std::forward<decltype(args)>(args)...);
RetWrapper<std::result_of_t<Tfunc(decltype(args)...)>> ret(
func, std::forward<decltype(args)>(args)...
);
after(std::forward<decltype(args)>(args)...);
return ret.value();
};
}
/*
* Tests
*/
float test1(float a, float b) {
std::cout << "Inside test1\n";
return a * b;
}
void test2() {
std::cout << "Inside test2\n";
}
int i = 0;
int &test3() {
return i;
}
int main() {
auto test1Deco = decorate(
test1,
[] (float a, float b) {
std::cout << "Calling test1 with " << a << " and " << b << '\n';
},
[] (float a, float b) {
std::cout << "Called test1 with " << a << " and " << b << '\n';
}
);
float c = test1Deco(3.5f, 5.1f);
std::cout << "Yields " << c << '\n';
auto test2Deco = decorate(
test2,
[] () {
std::cout << "Calling test2\n";
},
[] () {
std::cout << "Called test2\n";
}
);
test2Deco();
auto test3Deco = decorate(
test3,
[] () {
std::cout << "Calling test3\n";
},
[] () {
std::cout << "Called test3\n";
}
);
auto &i2 = test3Deco();
i2 = 42;
std::cout << "Global i = " << i << '\n';
return 0;
}
Output :
Calling test1 with 3.5 and 5.1
Inside test1
Called test1 with 3.5 and 5.1
Yields 17.85
Calling test2
Inside test2
Called test2
Calling test3
Called test3
Global i = 42
Just go full template, without std::function:
template< typename Func >
class FunctionDecorator
{
public:
FunctionDecorator( Func func )
: m_func( std::move(func) )
{}
void operator()()
{
// do some stuff prior to function call
m_func();
// do stuff after function call
}
private:
Func m_func;
};
template< typename Func >
FunctionDecorator<Func> decorate(Func func) {
return FunctionDecorator<Func>(std::move(func));
}
[Note: edited a few hours after initial posting]
This perhaps isn't exactly what the OP was looking for, but it's still relevant and hopefully useful to others looking for answers.
Let's say you have a couple of functions that have slightly different signatures:
void foo1(int& x){ cout << "foo1(" << x << ")\n";}
void foo2(double& x){ cout << "foo2(" << x << ")\n";}
and you'd like to wrap a decorator around them both so as to standardise their signatures, e.g. turn them both into void (*)(int).
Then you could do the following:
template<typename Q, void (*foo_p)(Q&)>
void wrapped(int x){
Q v = 42.2 + x;
foo_p(v);
}
int main(){
using foo_t = void (*)(int); // we coerce foo1 and foo2 into this type
foo_t k_int = wrapped<int, foo1>;
foo_t k_double = wrapped<double, foo2>;
k_int(-1); //cout: foo1(41)
k_double(-1); //cout: foo2(41.2)
return 0;
}
Using the example main I've given here, clang inlines the whole thing, which is a good sign but not quite what we wanted to check. If you make the example a bit more complex (see live here) you can see that it does indeed inline everything within each wrapper, i.e. foo1 and foo2 don't exist in standalone form, only in wrapped form.
Originally, I use a lambda in addition to the wrapped<...> template (making use of the fact that lambdas with no-capture can be converted to function pointers) but then I realized that the extra wrapping was redundant in this case.
This method should work for passing anything known at run time, which could even include a pointer to a mutable global (although that's getting pretty messy).
#include <iostream>
#include <string>
using namespace std;
template <typename TResult, typename TParams>
class CClassGenerique
{
typedef TResult (*uneFonction) (TParams);
public :
CClassGenerique (uneFonction f){ m_function = f; }
void operator () (TParams t) { m_function (t); }
private :
uneFonction m_function;
};
template <typename TResult, typename TParams>
TResult BasicFunction (TParams p)
{
TResult t=0;
std::cout<<" Value = " << p <<endl;
return t;
}
int main (int argc, char* argv[])
{
CClassGenerique<int, int> c1 (BasicFunction<int, int>);
CClassGenerique<int, char*> c2 (BasicFunction<int, char*>);
CClassGenerique<char*, char*> c3 (BasicFunction<char*, char*>);
c1(3);
c2("bonsoir");
c3("hello");
return 0;
}
I have checked questions that are similar. This is close, but not a duplicate.
In essence I want to call a function on a parameter pack of base classes if present. I have a C++11 way of doing this that works, but it does not feel satisfactory to me.
Can someone offer a better [i.e. better performance and less boilerplate code]:
source code:
#include <iostream>
#include <type_traits>
using namespace std;
// a class initialised with an int that can't do it
struct A
{
A(int a) : _a(a) { }
void report() const { std::cout << _a << std::endl; }
private:
int _a;
};
// a class initialised with a string that can do it
struct B
{
B(std::string s) : _b (move(s)) { }
void report() const { std::cout << _b << std::endl; }
void do_it() { std::cout << "B did it with " << _b <<"!" << std::endl; }
private:
string _b;
};
// a class initialised with an int that can do it
struct D
{
D(int d) : _d(d) { }
void report() const { std::cout << _d << std::endl; }
void do_it() { std::cout << "D did it with " << _d <<"!" << std::endl; }
private:
int _d;
};
// a class initialised with a string that can't do it
struct E
{
E(std::string s) : _e(move(s)) { }
void report() const { std::cout << _e << std::endl; }
private:
string _e;
};
// a function enabled only if T::do_it is a member function pointer
// the bool is there just to make this function more attractive to the compiler
// than the next one, below
template<class T>
auto do_it(T& t, bool)
-> typename std::enable_if<std::is_member_function_pointer<decltype(&T::do_it)>::value, void>::type
{
t.do_it();
}
// a catch-all function called when do_it<T> is not valid
// the ... is less attractive to the compiler when do_it<T>(T&, bool) is available
template<class T>
void do_it(T& t, ...)
{
}
// a compound class derived from any number of classes - I am so lazy I work hard at
// being lazy.
template<class...Templates>
struct C : public Templates...
{
// construct from a parameter pack of arbitrary arguments
// constructing each base class with one argument from the pack
template<class...Args>
C(Args&&...args)
: Templates(std::forward<Args>(args))...
{
}
// private implementation of the dispatch mechanism here...
private:
// this will call ::do_it<T>(T&, bool) if T::do_it is a member function of T, otherwise
// calls ::do_it<T>(T&, ...)
template<class T>
void may_do_it()
{
::do_it(static_cast<T&>(*this), true);
}
// calls may_do_it for the last class in the parameter pack
template<typename T1>
void multi_may_do_it()
{
may_do_it<T1>();
}
// general case for calling do_it on a parameter pack of base classes
template<typename T1, typename T2, typename...Rest>
void multi_may_do_it()
{
may_do_it<T1>();
multi_may_do_it<T2, Rest...>();
}
// calls may_do_it for the last class in the parameter pack
template<typename T1>
void multi_report() const
{
static_cast<const T1&>(*this).report();
}
// general case for calling do_it on a parameter pack of base classes
template<typename T1, typename T2, typename...Rest>
void multi_report() const
{
static_cast<const T1&>(*this).report();
multi_report<T2, Rest...>();
}
// the functions we actually wish to expose here...
public:
// disptach T::do_it for each valid T in base class list
void do_it() {
multi_may_do_it<Templates...>();
}
// dispatch T::report, which must exist for each base class
void report() const {
cout << "-- all base classes reporting:" << endl;
multi_report<Templates...>();
cout << "-- all base classes reported" << endl;
}
};
int main()
{
C<A,B, D, E> c(10, "hello", 7, "goodbye");
c.report(); // all base classes must report
c.do_it(); // all base classes that can do_it, must.
return 0;
}
output:
Compiling the source code....
$g++ -std=c++11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1
Executing the program....
$demo
-- all base classes reporting:
10
hello
7
goodbye
-- all base classes reported
B did it with hello!
D did it with 7!
I think this is about as boilerplate-free as you can make it.
// a function enabled only if T::do_it is a member function pointer
template<class T>
auto do_it(T* t)
-> typename std::enable_if<std::is_member_function_pointer<decltype(&T::do_it)>::value, void>::type
{
t->do_it();
}
// a catch-all function called when do_it<T> is not valid
// the const void * is less attractive to the compiler when do_it<T>(T*) is available
template<class T>
void do_it(const void *)
{
}
// a compound class derived from any number of classes - I am so lazy I work hard at
// being lazy.
template<class...Templates>
struct C : public Templates...
{
//constructor omitted
private:
using expander = int[];
public:
// disptach T::do_it for each valid T in base class list
void do_it() {
(void) expander{ 0, (::do_it<Templates>(this), 0)...};
}
// dispatch T::report, which must exist for each base class
void report() const {
cout << "-- all base classes reporting:" << endl;
(void) expander{ 0, (Templates::report(), 0)...};
cout << "-- all base classes reported" << endl;
}
};
Demo.
I have a such factories, which instantiate objects by passed template class name T:
template<class T>
class Factory0
{
public:
static void *Create(){ return new T(); }
};
template<class T, class Argument1>
class Factory1
{
public:
static void *Create( Argument1 &arg1 ){ return new T( arg1 ); }
};
And i need to do something like such:
map<string[ClassName], &factory] _builder;
...
template<class T>
Add(){
if( T derived from BaseClass ) _builder[T] = &factory1::Create
else if( T derived from BaseClass ) _builder[T] = &factory0::Create;
}
template<class T>
Create() {
return _builder[T]( (factory0) ? <nothing> : <some_argument> );
}
This is hard for two reasons:
Calling create with the wrong arguments can only be caught at runtime, so we need a bit of dynamic typing.
C++ really doesn't like casting function pointers. Or creating pointers to templated functions. Or generally doing anything complex with function pointers.
But it can be done:
#include<string>
#include<map>
#include<iostream>
using namespace std;
struct returnable {
// Put some interesting virtual functions here
};
struct foo : public returnable {
foo() {
cout << "defaulFoo" << endl;
}
foo(int x) {
cout << "Foo:" << x << endl;
}
};
struct bar : public returnable {
bar(char a, char b){
cout << "bar:" << a << "," << b << endl;
}
};
template<typename... ARGS>
struct newmakerbase {
virtual returnable* make(ARGS... args) = 0;
};
template<typename OUT, typename... ARGS>
struct newmaker : public newmakerbase<ARGS...> {
virtual returnable* make(ARGS... args) {
return new OUT(args...);
}
};
// Boost might provide a neater version of this
int nextId = 0;
template<typename... T>
struct typeId {
static const int id;
};
template<typename... T>
const int typeId<T...>::id = nextId++;
map<string,void*> builders;
map<string,int> argtypes;
template<typename OUT, typename... ARGS>
void registerClas(string name) {
builders[name] = static_cast<void*>(new newmaker<OUT,ARGS...>());
argtypes[name] = typeId<ARGS...>::id;
}
template<typename... ARGS>
returnable* create(string name, ARGS... args) {
int argsgiven = typeId<ARGS...>::id;
if (argsgiven != argtypes[name]) {
// TODO: maybe throw an exception or something?
return NULL;
}
newmakerbase<ARGS...>* builder = static_cast<newmakerbase<ARGS...>*>(builders[name]);
return builder->make(args...);
}
main() {
registerClas<foo>("defaultFoo");
registerClas<foo,int>("foo");
registerClas<bar,char,char>("bar");
returnable* a = create("defaultFoo");
returnable* b = create("foo", 42);
returnable* c = create("foo", 'a', 'b'); // returns NULL
returnable* d = create("foo", 42.0); // also returns NULL
returnable* e = create("bar", 'c', 'd');
cout << a << " " << b << " " << c << " " << d << " " << e << endl;
}