Pass block of statements as arguement to the function call - c++

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

Related

invoking member functions from producer thread

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

Multiple functions for a class does not store previous results

Problem
I want to create a function inside a class which function2 will use the result generated from function1. I have a small code snippet where I tried to make it easy to understand.
#include <stdio.h>
class GreaterSmaller {
public:
int greater, smaller;
};
GreaterSmaller findGreaterSmaller(int a, int b)
{
GreaterSmaller s;
if (a > b) {
s.greater = a;
s.smaller = b;
}
else {
s.greater = b;
s.smaller = a;
}
return s;
}
GreaterSmaller print()
{
GreaterSmaller s;
std::cout << s.greater << s.smaller << std::endl;
}
int main()
{
int x = 4;
int y = 3;
GreaterSmaller result;
result = findGreaterSmaller(x, y);
result = print(); // I want it to print 4 & 3
return 0;
}
P.s Just wanted to mention I am not trying to print the result in the function2 I have created that for a demo.
Define the second method as taking an argument of the first type, and pass it when you call it, as such:
void print(GreaterSmaller &s)
{
std::cout << s.greater << s.smaller << std::endl;
}
print(result); // I want it to print 4 & 3

How to fix class function behaviour based on initialization parameters

I am creating a C++ class which takes certain parameters during initialization and has some functions based on its private variables, something like the compute function here:
class A {
public:
A(int x){
a = x;
}
int compute(int y){
if (a == 0){
return y*y;
}
else if (a == 1){
return 2*y;
}
else{
return y;
}
}
private:
int a;
};
// usage
A myA(1); // private variables set only once
myA.compute(10); // this will check value of a
myA.compute(1); // this will check value of a
Given that the private variables are set during initialization and will not be changed again, is there any efficient way to avoid the condition check related to the private variables during runtime?
Any and all assistance is appreciated. Thank you
You can template the function compute() on an int and use the template value as parameter. You can see the result at https://godbolt.org/z/14Mh4E
class A {
public:
A(int x) {
a = x;
}
template <int y>
constexpr int compute() const {
if (a == 0) {
return y * y;
}
else if (a == 1) {
return 2 * y;
}
else {
return y;
}
}
private:
int a;
};
// usage
A myA(1); // private variables set only once
myA.compute<10>(); // this will check value of a
myA.compute<1>(); // this will check value of a
You could avoid the condition check if you would use e.g. a function object as a member, and set this conditioned on the value of variable a.
Anyway, I don't think that the condition check will be big performance issue. But this will depend on your application of course.
#include <functional>
#include <iostream>
class A {
public:
A(int x)
: a { x }
{
if (a == 0){
compute = [](int y){ return y*y; };
}
else if (a == 1){
compute = [](int y){ return 2*y; };
}
else{
compute = [](int y){ return y; };
}
}
std::function<int(int)> compute;
private:
int a;
};
// usage
int main()
{
A myA(1); // private variables set only once
std::cout << myA.compute(10) << std::endl;
std::cout << myA.compute(1) << std::endl;
return 0;
}
You can guarantee the conditions are evaluated at compile time by using constexpr. Note that in this case you must use C++14 for constexpr compute(...), as multiple return statements are only suppoerted in constexpr functions after C++14.
#include <iostream>
class A {
public:
constexpr A(const int x): a(x) { }
constexpr int compute(const int y) const {
// Multiple return statements inside a constexpr function
// requires C++14 or above.
if (a == 0) {
return y*y;
}
else if (a == 1) {
return 2*y;
}
else {
return y;
}
}
private:
int a;
};
int main() {
constexpr A myA(1);
constexpr int num = myA.compute(123);
std::cout << num << std::endl;
return EXIT_SUCCESS;
}
This page contains a good explanation of constexpr, as well as examples.
If parameters are runtime value, I don't see an optimal way to avoid condition or jump.
You can trade your condition by virtual call:
struct A
{
virtual ~A() = default;
virtual int compute(int) = 0;
};
struct A0 { int compute(int y) override { return y * y; } };
struct A1 { int compute(int y) override { return 2 * y; } };
struct AN { int compute(int y) override { return y; } };
std::unique_ptr<A> makeA(int a)
{
switch (a) {
case 0: return std::make_unique<A0>();
case 0: return std::make_unique<A1>();
default: return std::make_unique<AN>();
}
}
(compiler might devirtualize the call if type is known at compile time)
or "equivalent":
struct A
{
int (*f)(int); // or even std::function<int(int)> f; if you need capture.
A(int a) : f(a == 0 ? +[](int y) { return y * y; }
: a == 1 ? +[](int y) { return 2 * y; }
: +[](int y) { return y; })
{}
int compute(int y) { return f(y); }
};
(erased-type is harder for compiler to devirtualize)

Wrapping functions in c++

I have a function executor which is called with function pointer and a general function origin which I wan't to pass with different parameters a and b to the executor. How can it be done?
Here is what I have tried so far:
#include <iostream>
void executor(float (*f)(float)) {
float x = 1.;
std::cout << (*f)(x) << std::endl;
}
float original(float x,float a,float b) {
return a*x + b;
}
//// Works as expected
float a = 1;
float b = 2;
float wrapped(float x) {
return original(x,a,b);
}
void call_executor_global() {
executor(wrapped);
}
//// FIRST TRY
// void call_executor_func(float a, float b) {
// float wrapped(float x) {
// return original(x,a,b);
// }
// executor(wrapped);
// }
//// SECOND TRY
// struct Wrapper {
// float a;
// float b;
// float func(float x) {
// return original(x,a,b);
// }
// };
// void call_executor_struct(float a, float b) {
// Wrapper wrapped;
// wrapped.a = a;
// wrapped.b = b;
// executor(wrapped.func);
// }
int main()
{
call_executor_global();
// call_executor_func(1,2);
// call_executor_struct(1,2);
}
You can wrap a function using several methods. It is easier if you make executor a function template.
template <typename F>
void executor(F f) {
float x = 1.;
std::cout << f(x) << std::endl;
}
Use a global function
float a = 1;
float b = 2;
float wrapped(float x) {
return original(x,a,b);
}
void call_executor_global1() {
executor(wrapped);
}
Use a lambda function
float a = 1;
float b = 2;
void call_executor_global2() {
executor([](float x) {return original(x, a, b);});
}
Use a functor
float a = 1;
float b = 2;
void call_executor_global3() {
struct wrapper
{
float operator()(float x) { return original(x, a, b); }
};
executor(wrapper());
}
See all of them working at http://ideone.com/rDKHC1.

C++ function pointer (class member) to non-static member function

class Foo {
public:
Foo() { do_something = &Foo::func_x; }
int (Foo::*do_something)(int); // function pointer to class member function
void setFunc(bool e) { do_something = e ? &Foo::func_x : &Foo::func_y; }
private:
int func_x(int m) { return m *= 5; }
int func_y(int n) { return n *= 6; }
};
int
main()
{
Foo f;
f.setFunc(false);
return (f.*do_something)(5); // <- Not ok. Compile error.
}
How can I get this to work?
class A{
public:
typedef int (A::*method)();
method p;
A(){
p = &A::foo;
(this->*p)(); // <- trick 1, inner call
}
int foo(){
printf("foo\n");
return 0;
}
};
void main()
{
A a;
(a.*a.p)(); // <- trick 2, outer call
}
The line you want is
return (f.*f.do_something)(5);
(That compiles -- I've tried it)
"*f.do_something" refers to the pointer itself --- "f" tells us where to get the do_something value from. But we still need to give an object that will be the this pointer when we call the function. That's why we need the "f." prefix.
class A {
int var;
int var2;
public:
void setVar(int v);
int getVar();
void setVar2(int v);
int getVar2();
typedef int (A::*_fVar)();
_fVar fvar;
void setFvar(_fVar afvar) { fvar = afvar; }
void insideCall() { (this->*fvar)(); }
};
void A::setVar(int v)
{
var = v;
}
int A::getVar()
{
std::cout << "A::getVar() is called. var = " << var << std::endl;
return var;
}
void A::setVar2(int v2)
{
var2 = v2;
}
int A::getVar2()
{
std::cout << "A::getVar2() is called. var2 = " << var2 << std::endl;
return var2;
}
int main()
{
A a;
a.setVar(3);
a.setVar2(5);
// a.fvar = &A::getVar;
a.setFvar(&A::getVar);
(a.*a.fvar)();
a.setFvar(&A::getVar2);
(a.*a.fvar)();
a.setFvar(&A::getVar);
a.insideCall();
a.setFvar(&A::getVar2);
a.insideCall();
return 0;
}
I extended Nick Dandoulakis's answer. Thank you.
I added a function which set the member function pointer from outside of the class. I added another function which can be called from outside to show inner call of member function pointer.
Try (f.*do_something)(5);
#include<iostream>
using namespace std;
class A {
public:
void hello()
{
cout << "hello" << endl;
};
int x = 0;
};
void main(void)
{
//pointer
A * a = new A;
void(A::*pfun)() = &A::hello;
int A::*v1 = &A::x;
(a->*pfun)();
a->*v1 = 100;
cout << a->*v1 << endl << endl;
//-----------------------------
A b;
void(A::*fun)() = &A::hello;
int A::*v2 = &A::x;
(b.*fun)();
b.*v2 = 200;
cout << b.*v2 << endl;
}
I think calling a non static member of the class could also be done using a static member function.