How to rewrite global functions for functions in a structure? - c++

I want function f2 in structure node to call function f1 in node instead of global function f1.
#include <iostream>
#include <functional>
int f1()
{
return 1;
}
int f2()
{
return f1();
}
struct node
{
int f1()
{
return 2;
}
std::function<int()> f2 = ::f2;
};
int main()
{
node a;
std::cout << a.f2() << "\n";
return 0;
}
I want function f2 in structure node to call function f1 in node instead of global function f1.

You can achieve this by adding a (second) constructor to node which accepts a callable to assign to node::f2. Something like this, passing in a lambda to that constructor to capture the object itself:
#include <iostream>
#include <functional>
int f1()
{
return 1;
}
int f2()
{
return f1();
}
struct node
{
node () = default;
node (std::function<int()> assign_to_f2) { f2 = assign_to_f2; }
int f1 ()
{
return 2;
}
std::function<int()> f2 = ::f2;
};
int main()
{
node a;
std::cout << a.f2() << "\n";
node b ([&b] () { return b.f1 (); });
std::cout << b.f2() << "\n";
return 0;
}
Output:
1
2
Live Demo

Related

Pass block of statements as arguement to the function call

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

Pointer to array of pointers to functions

The idea is to call different functions based on their index in table.
But line 27 generates the runtime error ((
I tried to fix but didn't succeed (((
Here's the simplified code:
#include <iostream>
void f1 (void) {
std::cout << "f1" << "\n";
}
void f2 (void) {
std::cout << "f2" << "\n";
}
typedef void (*fPtr[3])(void); // simple "[]" instead of "[3]" gets the compile error
class modeChanger {
public:
modeChanger (fPtr funcArray);
void op ();
private:
fPtr *_funcArray;
};
modeChanger::modeChanger (fPtr funcArray) {
_funcArray = (fPtr *) funcArray;
}
void modeChanger::op () {
(*_funcArray[0])();
(*_funcArray[1])(); // Line 27: this line generates a runtime error! Just comment it to get all work
}
void (*modeFuncArray[])(void) = {f1, f2, f2};
modeChanger *mode = new modeChanger (modeFuncArray);
int main() {
(*modeFuncArray[1])(); // Works fine
mode->op(); // generates a runtime error
return 0;
}
This works good:
(*_funcArray[0])();
as well as this:
(*modeFuncArray[1])();
but this generates a runtime error...
(*_funcArray[1])();
Seems that incrementing of _funcArray is incorrect for some reason.
fPtr *_funcArray; this is the pointer to array, not an array of pointers. You suppressed warnings with help of type casts. See bellow the fixed code.
#include <iostream>
void f1 (void) {
std::cout << "f1" << "\n";
}
void f2 (void) {
std::cout << "f2" << "\n";
}
typedef void (*fPtr)(void);
class modeChanger {
public:
modeChanger (fPtr *funcArray);
void op ();
private:
fPtr *_funcArray;
};
modeChanger::modeChanger (fPtr *funcArray) {
_funcArray = funcArray;
}
void modeChanger::op () {
(*_funcArray[0])();
(*_funcArray[1])(); // Line 27: this line generates a runtime error! Just comment it to get all work
}
void (*modeFuncArray[])(void) = {f1, f2, f2};
modeChanger *mode = new modeChanger (modeFuncArray);
int main() {
(*modeFuncArray[1])(); // Works fine
mode->op(); // generates a runtime error
return 0;
}
Applying #Someprogrammerdude's advice:
#include <iostream>
#include <array>
#include <functional>
void f1 (void) {
std::cout << "f1" << "\n";
}
void f2 (void) {
std::cout << "f2" << "\n";
}
using fPtr = std::function<void()>;
using fPtrs = std::array<fPtr, 3>;
class modeChanger {
public:
modeChanger (fPtrs funcArray);
void op ();
private:
fPtrs _funcArray;
};
modeChanger::modeChanger (fPtrs funcArray) : _funcArray(funcArray) { }
void modeChanger::op () {
_funcArray[0]();
_funcArray[1]();
}
int main() {
fPtrs modeFuncArray = {f1, f2, f2};
modeChanger mode(modeFuncArray);
modeFuncArray[1]();
mode.op();
return 0;
}
And thus instead of "hard to declare" C types, we have things as easy as int, and all is well.
as you use c++, you should use c++ features and not C, you should use <functional>
#include <iostream>
#include <functional>
void f1(void) {
std::cout << "f1" << "\n";
}
void f2(void) {
std::cout << "f2" << "\n";
}
typedef void(*fPtr[3])(void); // simple "[]" gets the compile error
class modeChanger {
public:
modeChanger(std::function<void(void)>* funcArray);
void op();
private:
std::function<void(void)> * _funcArray;
};
modeChanger::modeChanger(std::function<void(void)>* funcArray) {
_funcArray = funcArray;
}
void modeChanger::op() {
_funcArray[0]();
_funcArray[1](); // this line generates a runtime error! Just comment it to get all work
}
std::function<void(void)> modeFuncArray[] = { f1, f2, f2 };
modeChanger *mode = new modeChanger(modeFuncArray);
int main() {
modeFuncArray[1](); // Works fine
mode->op(); // generates a runtime error
return 0;
}

C++ use lambda function as template function specialization

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

Passing function as an argument to different function in different file

So, I want to pass function, that is in engine.cpp file, as an argument, and that's what I did:
typedef RFun(*wsk)(double, int);
RFun Engine::f_line(double *&values, int howmany)
{
RFun line;
for(int i = 0; i < howmany; i++)
{
line.result_values[i] = (2 * values[i]) + 6;
}
return line;
}
RFun counter(double *&values, int howmany, wsk function)
{
return function(*values, howmany);
}
and now I want to call the counter function in other .cpp file and pass f_line function inside as parameter. How can I achieve that?
Here is a simple example how to use std::function.
#include <iostream>
#include <functional>
using namespace std;
void func1()
{
// a function that takes no parameters and does nothing
cout << "in global func1" << endl;
}
class Example
{
public:
int value;
void memberfunc()
{
cout << "in memberfunc. value=" << value << endl;
}
};
void CallAFunction( std::function< void() > functocall )
{
functocall(); // call it normally
}
int main()
{
// call a global function
CallAFunction( func1 ); // prints "in global func1"
// call a member function (a little more complicated):
Example e;
e.value = 10;
CallAFunction( std::bind( &Example::memberfunc, std::ref(e) ) );
// prints "in memberfunc. value=10"
}
Try it out here
Success time: 0 memory: 15240 signal:0
in global func1
in memberfunc. value=10

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.