Using a producer-consumer pattern I'd like to submit calls to the member functions of struct A i.e., func_1() and func_2() by passing the name of the function object (something like A::func_1), and a list of arguments taken by these functions in a queue-like buffer queue_in. I'd then like to collect these results (here a std::variant of all the possible return types (double and int)) in another buffer queue_out for later processing.
At the moment, I'm only able to hack my way by having q_in hold std::string and enumerating all the possibilities manually. Of course I'm also missing passing any possible arguments to func_1() and func_2().
#include <iostream>
#include "blockingconcurrentqueue.h" // https://github.com/cameron314/concurrentqueue
#include <variant>
using Result = std::variant<double, int>;
using queue_in = moodycamel::BlockingConcurrentQueue<std::string>;
using queue_out = moodycamel::BlockingConcurrentQueue<Result>;
struct A {
explicit A(queue_in &q_in, queue_out &q_out) {
std::thread t([&]() {
for (;;) {
std::string s;
if (q_in.wait_dequeue_timed(s, -1)) {
if (s == "1")
q_out.enqueue(this->func_1());
else if (s == "2")
q_out.enqueue(this->func_2());
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
t.join();
}
double func_1() const { // func_1 might have arguments!
std::cout << "func_1() called.\n";
return 13.0f;
}
int func_2() const { // func_2 might have arguments!
std::cout << "func_2() called.\n";
return 1;
}
};
void producer(queue_in &q_in, const size_t N) {
for (size_t i = 0; i != N; ++i) {
q_in.enqueue("1" /*..., arguments for func_1*/); // prefer to call the function-object instead
q_in.enqueue("2" /*..., arguments for func_2*/);
}
}
void result_consumer(queue_out &q_out) {
for (;;) {
Result r;
if (q_out.wait_dequeue_timed(r, -1)) {
std::visit([](auto &&arg) {
std::cout << "The result is: " << arg << std::endl;
}, r);
}
std::this_thread::sleep_for(std::chrono::seconds(0));
}
}
int main() {
const size_t N = 2;
queue_in q_in;
queue_out q_out;
std::thread producer_thread(producer, std::ref(q_in), N);
std::thread result_consumer_thread(result_consumer, std::ref(q_out));
A a(q_in, q_out);
producer_thread.join();
result_consumer_thread.join();
}
How can I do this instead via function objects? Second, how do I invoke any possible arguments for the member functions of A. And third, can I avoid the use of a std::variant like result type?
Taking inspiration from #n.1.8e9-where's-my-sharem. 's comments here's how I got the above to work using std::function and std::bind
using Result = std::variant<double, int>;
using FO = std::function<Result(void)>;
using queue_in = moodycamel::BlockingConcurrentQueue<FO>;
using queue_out = moodycamel::BlockingConcurrentQueue<Result>;
struct A {
explicit A(queue_in &q_in, queue_out &q_out) {
std::thread t([&]() {
for (;;) {
FO o;
if (q_in.wait_dequeue_timed(o, -1)) {
q_out.enqueue(o());
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
t.detach();
}
void consumer() {
}
double func_1(double x, const size_t &s) const { // note the arguments
std::cout << "func_1() called.\n";
return x + s;
}
int func_2(int x) const {
std::cout << "func_2() called.\n";
return x;
}
};
void producer(const A& a, queue_in &q_in, const size_t N) { // note the first argument: the producer() must know about some instance of A
for (size_t i = 0; i != N; ++i) {
FO o;
if (i % 2 == 0)
o = std::bind(&A::func_1, a, double(i), size_t(10));
else
o = std::bind(&A::func_2, a, int(i));
q_in.enqueue(o);
}
}
void result_consumer(queue_out &q_out) {
for (;;) {
Result r;
if (q_out.wait_dequeue_timed(r, -1)) {
std::visit([&](auto &&arg) {
std::cout << "The result is: " << arg << std::endl;
}, r);
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main() {
const size_t N = 2;
queue_in q_in;
queue_out q_out;
A a(q_in, q_out);
std::thread producer_thread(producer, std::ref(a), std::ref(q_in), N);
std::thread result_consumer_thread(result_consumer, std::ref(q_out));
producer_thread.join();
result_consumer_thread.join();
}
Output:
func_1() called.
The result is: 10
func_2() called.
The result is: 1
Related
Consider the following example:
func(cond, block_A, block_B) {
if(cond) {
block_A; // Run all the statements in the block A
} else {
block_B; // Run all the statements in the block B
}
}
int main() {
block_A = {
y = 1;
std::cout << (y);
// statement continues ...
}
block_B = {
z = 1;
std::cout << (z);
// statement continues ...
}
func(true, block_A, block_C);
}
Is there any way to pass a block of statements as an argument to the function call?
You can pass callables to func and use lambda expressions:
#include <iostream>
template <typename F,typename G>
void func(bool cond, F a, G b) {
if(cond) {
a(); // Run all the statements in the block A
} else {
b(); // Run all the statements in the block B
}
}
int main() {
auto block_A = [](){
int y = 1;
std::cout << y;
};
auto block_B = [](){
int z = 1;
std::cout << z;
};
func(true, block_A, block_B);
}
At first it seemed clear that I shouldn't be able to do this, but then I discovered that it can be done with free functions.
Here is an example where I pass void() functions from Child to Parent. The parent calls the function when their Frame comes up.
I have figured out the syntax to pass free functions with arguments, but I can't figure out how to pass a member function of Child with an argument.
Please help.
#include <iostream>
#include <vector>
#include <map>
#include <functional>
void f_Free1() { std::cout << "Hi there hello. I'm a free function without arguments."; }
void f_Free2(int i) { std::cout << "Hi there hello. I'm a free function with an argument. It's " << i; }
class Parent
{
std::map<unsigned int, std::vector<std::function<void()>>> Tasks;
protected:
void addTask(unsigned int frame, std::function<void()> task) { Tasks[frame].push_back(task); }
public:
virtual ~Parent() {}
unsigned int Frame = 0;
void tick()
{
if (Tasks.count(Frame))
{
for (auto task : Tasks[Frame])
{
task();
}
}
Frame++;
}
};
class Child : public Parent
{
void f_Child1() { std::cout << "This is a private Child function without arguments. "; }
void f_Child2(int i) { std::cout << "This is a private Child function with an argument. It's " << i; }
public:
Child()
{
addTask(3, f_Free1);
addTask(5, [a = int(4)] () { f_Free2(a); } ); // THIS WORKS!!!
addTask(7, std::function<void()> { std::bind(&Child::f_Child1, this) });
addTask(9, std::function<void()> { std::bind([a = int(4)]() { &Child::f_Child2(a), this) } }); // CAN'T MAKE THIS WORK
}
};
int main()
{
Child child;
for (unsigned int i = 0; i < 12; i++)
{
std::cout << "[" << child.Frame << "]";
child.tick(); // runs tasks whose frames are up
std::cout << std::endl;
}
return 0;
}
Ditch the bind.
Use [this]() { f_Child1(); } and [this]() { f_Child(4); }.
Also, the free version can be just []() { f_Free2(4); }.
std::bind's syntax would be:
std::bind(&f_Free1)
std::bind(&f_Free2, 4)
std::bind(&Child::f_Child1, this)
std::bind(&Child::f_Child2, this, 4)
But lambda is simpler for most people:
&f_Free1 is fine, else [](){ return f_Free1(); }
[](){ return f_Free2(4); }
[this]() { return this->f_Child1(); )
[this]() { return this->f_Child2(4); )
return can be omitted here as functions return void.
this-> can be omitted in lambda.
you might capture more or differently for arguments.
I want to be able to return a function from a class, so that I do not need to if-else through a return type.
I have a class that returns multiple strings. Instead, I want to return multiple functions.
#include <iostream>
class Handler
{
private:
public:
int handleMessage(int code)
{
return code+1;
}
};
void func1();
void func2();
void func3();
int main (int argc, char *argv[])
{
Handler handle;
int code = handle.handleMessage(0);
if(code == 1)
{
func1();
}
return 0;
}
void func1(){ std::cout << "1" << std::endl;}
void func2(){ std::cout << "2" << std::endl;}
void func3(){ std::cout << "3" << std::endl;}
What I want is: That the function handleMessage in the class Handler returns something so that in my main application I do not have to use if-else.
So the main looks like this:
function = handle.handleMessage(0);
And the application will choose which function it will run.
for example:
function = handle.handleMessage(0); //will run func1
function = handle.handleMessage(1); //will run func2
You can modify the member function such that it returns a function pointer, e.g.
using fptr = void (*)();
struct Handler
{
fptr handleMessage (int code)
{
if (code == 0)
return &func1;
else if (code == 1)
return &func2;
else
return &func3;
}
};
This can be invoked as follows
Handler handle;
auto f = handle.handleMessage(0);
f();
Note that the above if-else if-else dispatch isn't ideal. Prefer a data member that stores the function pointers and associates them with a code, e.g. using a std::unordered_map.
Note that when you need to return stateful function objects in the future, this approach will fail. Then, you need to embrace std::function which is able to wrap lambdas with closures or custom types with an operator() overload.
There are several ways to do so, the simplest one, you can use an std::function. In this example we returning a lambda function for each case. You can replace it with the functions you just wrote.
class Handler {
public:
std::function<void()> handleMessage(int code) {
code = code + 1; // ++code or whatever
if (code == X) {
return []() { std::cout << "Cool! I'am x!" << std::endl; };
} else if (code == Y) {
return []() { std::cout << "Cool! I'am x!" << std::endl; };
} else if (...) {
...
} else {
....
}
}
};
Then your main function becomes:
int main (int argc, char *argv[]) {
Handler handle;
const auto func = handle.handleMessage(0);
func();
return 0;
}
You can replace the swith/if case statement by an array storing the different functions, like they mentioned in the comments.
If you dont want to pay the extra virtual function call regarding the usage of an std::function, you can use an alias like the answer below or just the auto keyword:
class Handler {
public:
constexpr auto handleMessage(int code) {
code = code + 1; // ++code or whatever
if (code == X) {
return &func1;
} else if (code == Y) {
return &func2;
} else if (...) {
...
} else {
....
}
}
};
std::function is a powerful tool. The tiny brother is a simple function pointer.
I transformed MCVE respectively to return a function pointer:
#include <iostream>
typedef void (*FuncPtr)();
void func1();
void func2();
void func3();
void funcError();
class Handler
{
private:
public:
FuncPtr handleMessage(int code)
{
switch (code + 1) {
case 1: return &func1;
case 2: return &func2;
case 3: return &func3;
default: return &funcError;
}
}
};
int main (int argc, char *argv[])
{
Handler handle;
FuncPtr pFunc = handle.handleMessage(0);
pFunc();
return 0;
}
void func1(){ std::cout << "1" << std::endl;}
void func2(){ std::cout << "2" << std::endl;}
void func3(){ std::cout << "3" << std::endl;}
void funcError(){ std::cout << "ERROR!" << std::endl;}
Output:
1
Live Demo on coliru
You can return a function with return_type(*function_name)(argument_type1, argument_type2...) so a function that looks like:
double f(int a, int b);
has the name double(*f)(int, int).
Worth mentioning is C++11's std::function which requires the <functional> header. It has a more intuitive usage: std::function<double(int, int)> but also adds a bit of overhead.
I would also like to suggest the usage of C++17's std::optional as for the case when the variable code goes out of bounds. This implementation requires the <optional> header.
std::optional<void(*)()> handleMessage(int code){
switch (code) {
case 0: return std::optional(func1);
case 1: return std::optional(func2);
case 2: return std::optional(func3);
}
return std::nullopt; //empty
}
usage in main looks like the following:
Handler handle;
auto func = handle.handleMessage(0);
if (func.has_value()) {
func.value()();
}
as this allows to check if func.has_value() which is quite convenient.
Use an array of functions.
void func1(){ std::cout << "1" << std::endl; }
void func2(){ std::cout << "2" << std::endl; }
void func3(){ std::cout << "3" << std::endl; }
typedef void (* func ) () ;
class Handler {
public:
func handleMessage(int code)const{
static const func F[] = { func1, func2, func3 };
return F[ code ];
}
};
int main()
{
Handler handler;
func f = handler.handleMessage(0); // returns func1
f();
}
live example
you can map the ints to a function or lambda, but read befor what at() does and what happens if the key is not found!!
void function1()
{
std::cout << "q1" << std::endl;
}
void function2()
{
std::cout << "q2" << std::endl;
}
int main(int argc, char* argv[])
{
std::map<int, std::function<void(void)>> map;
map.insert(std::make_pair(1, function1));
map.insert(std::make_pair(1, function2));
map.at(1)();
I would like to offer solution without any if-else block. You just need to templatize your Handler::handleMessage function. Something like this:
// Class declaration
class Handler
{
private:
public:
template<int code>
void handleMessage();
};
and specialize the function template for particular codes:
// Function template specializations.
template<>
void Handler::handleMessage<1>()
{
std::cout << "1" << std::endl;
}
template<>
void Handler::handleMessage<2>()
{
std::cout << "2" << std::endl;;
}
template<>
void Handler::handleMessage<3>()
{
std::cout << "3" << std::endl;;
}
// All cases, except 1, 2 and 3
template<int code>
void Handler::handleMessage()
{
std::cout << "Anything else" << std::endl;;
}
The usage may look like:
Handler h;
h.handleMessage<1>(); // Prints 1
h.handleMessage<2>(); // Prints 2
h.handleMessage<3>(); // Prints 3
h.handleMessage<323>(); // Prints 'Anything else'
Is it possible to use a lambda function to create an alias to a template class function? Something like this:
#include <iostream>
using namespace std;
int calcDouble(int a) { return a * 2; }
int calcMultiply_10(int a) { return a * 10; }
struct foo
{
template<void (*func)(int)>
int generic(int value)
{
return func(value);
}
static auto double_10 = [this] { generic<calcDouble>(10); };
static auto double_20 = [this] { generic<calcDouble>(20); };
static auto multiply_10_20 = [this] { generic<calcMultiply_10>(20); };
}
int main() {
foo f;
cout << "double_10: " <<f.double_10() << endl;
cout << "double_20: " <<f.double_20() << endl;
return 0;
}
Your particular example doesn't compile, and would be dangerous if it did - capturing this by value means that as soon as the class is copied/moved the captured this will point to a wrong or invalid memory location.
Just use member functions:
auto double_10() { return generic<calcDouble>(10); }
auto double_20() { return generic<calcDouble>(20); }
auto multiply_10_20() { return generic<calcMultiply_10>(20); }
live example on wandbox
I've just found something as get the name of current function or get name of the caller, some variants to get or call the name as string.
What I want is to get the name of the function that I passed in arguments. Like this:
void Bar()
{
//do something
}
void Foo(void (*f)())
{
//this will output: Foo
std::cout << __FUNCTION__ << std::endl;
//How do I get the name passed to f? (in this case: Bar)
}
int main()
{
Foo(Bar);
return 0;
}
Thanks.
Edit: Here is an extremely near code for what I'm trying following the suggestion of #Jose.
thread_local const char * m_last_function_called = "";
#define register_function() {m_last_function_called = __FUNCTION__;}
inline const char * get_last_function() { return m_last_function_called; }
// const char * g_last_function_called = "";
// #define register_function() { g_last_function_called = __FUNCTION__; }
// inline const char * get_last_function() { return g_last_function_called; }
void print_last_func()
{
static std::mutex sync_cout;
std::lock_guard<std::mutex> l(sync_cout);
std::cout << get_last_function() << std::endl;
}
bool interruptFooTimer = false;
int FooTimer()
{
register_function();
print_last_func();
std::cout << "FooTimer.start" << std::endl;
int t = 0;
while(t<10)
{
if(interruptFooTimer==false)
{
sleep(1);
t++;
std::cout << "\tt=" << t << std::endl;
}
else
{
return -1;
}
}
std::cout << "FooTimer.end" << std::endl;
return 0;
}
void CallTrd(int (*f)())
{
std::thread TrdTemp(f);
TrdTemp.detach();
TrdTemp.~thread();
print_last_func();
}
int main()
{
CallTrd(FooTimer);
print_last_func();
int c = 0;
while(c<15)
{
if(c==7) {interruptFooTimer=true;}
sleep(1);
c++;
std::cout << "c=" << c << std::endl;
print_last_func();
}
return 0;
}
Observe that I call print_last_func() in different moments and all get the same value that was initialized in the variable. This sample code calls a thread without using join() because I can't wait for the thread to finish and also implement the detach() and ~thread to finish my program without any exception. The interruptFooTimer I'm using to safely "terminate" my thread.
What am I missing to get global the value acquired in register_function??
You cannot. __FUNCTION__ is expanded by compiler during the compilation time. You cannot get this information in runtime.
Use a helper macro:
#define Foo(x) FooHelper(#x, x)
void FooHelper(const char *f_name, void (*f)())
{
cout << f_name;
}
As others have already noted, you cannot do this directly.
First of all I would use std::function instead of a raw function pointer and std::string to hold the function's name.
I would also wrap these up like this:
template<class T>
struct Functor
{
std::function<T> functor_;
std::string name_;
Functor(const std::function<T>& functor, const std::string& name)
: functor_(functor)
, name_(name)
{}
};
You can then use it like so:
void Bar()
{
// do something
}
void Foo(const Functor<void()>& functor)
{
}
int main()
{
Functor<void()> f(std::bind(Bar), "Bar");
Foo(f);
return 0;
}
You can also use a macro to make things easier for you.
#define FUNCTOR(t, x, ...) Functor<t>(std::bind(&x, __VA_ARGS__), #x)
Which can be used like this:
int main()
{
auto f = FUNCTOR(void(), Bar);
return 0;
}
Note that if you take this approach that the function name might not be the same as what using __FUNCTION__ yields.
I don't know why you wanna do it, but I hope it's for debugging purpose. Obviously the easiest path is to pass the __FUNCTION__ as an argument as pointed out. But in my point of view, there's a better approach.
You could have for example, a global variable:
thread_local const char * g_last_function_called = "";
#define register_function() { g_last_function_called = __FUNCTION__; }
inline const char * get_last_function() { return g_last_function_called; }
void Bar()
{
register_function()
}
void Foo(void (*f)())
{
std::cout << get_last_function() << std::endl;
}
void my_func_that_doesnt_accept_nulls(CClass * p)
{
if (p == nullptr)
{
std::cout << " function" << get_last_function();
std::cout << "passed a bad pointer, fix it" << std::endl;
return;
}
}
Of course, this will not give you the right result in multi-thread, but you can probably fix that using a thread_local const char * g_last_function_called = "" variable.
The reason why I like this method is because all you have to do to remove it from your project is just a simple "find and replace" of register_function(), and since it uses plain pointers, there's no way it can slow your program at all.
Edit: this is how I'm testing the code
void print_last_func()
{
static std::mutex sync_cout;
std::lock_guard<std::mutex> l(sync_cout);
std::cout << get_last_function() << std::endl;
}
void HelloWorld1()
{
register_function();
print_last_func();
}
void HelloWorld2()
{
register_function();
print_last_func();
}
int main()
{
register_function();
std::thread t1(HelloWorld1);
std::thread t2(HelloWorld2);
print_last_func();
t1.join();
t2.join();
return 0;
}
I get: HelloWorld1, HelloWorld2, and main