Say we have 2 functions
foo() { cout << "Hello"; }
foo2() { cout << " wolrd!"; }
how can i create an array of pointers (say a, b), with a pointing to foo() and b to foo2() ?
my goal is to store these pointers in an array A, then loop over A to execute these functions.
You can use typed function pointers as follows:
using FunPtrType = void(*)();
FunPtrType arr[]{&foo, &foo2};
// or
std::array<FunPtrType, 2> arr2{&foo, &foo2};
// ... do something with the array of free function pointers
// example
for(auto fun: arr2)
fun();
There is a simple implementation:
#include <iostream>
#include <vector>
using namespace std;
// Defining test functions
void a(){cout<<"Function A"<<endl;}
void b(){cout<<"Function B"<<endl;}
int main()
{
/*Declaring a vector of functions
Which return void and takes no arguments.
*/
vector<void(*)()> fonc;
//Adding my functions in my vector
fonc.push_back(a);
fonc.push_back(b);
//Calling with a loop.
for(int i=0; i<2; i++){
fonc[i]();
}
return 0;
}
There's no need for typedefs these days, just use auto.
#include <iostream>
void foo1() { std::cout << "Hello"; }
void foo2() { std::cout << " world!"; }
auto foos = { &foo1, &foo2 };
int main() { for (auto foo : foos) foo(); }
There are two equivalent ways to do what you want:
Method 1
#include <iostream>
void foo()
{
std::cout << "Hello";
}
void foo2()
{
std::cout << " wolrd!";
}
int main()
{
void (*a)() = foo;// a is a pointer to a function that takes no parameter and also does not return anything
void (*b)() = foo2;// b is a pointer to a function that takes no parameter and also does not return anything
//create array(of size 2) that can hold pointers to functions that does not return anything and also does not take any parameter
void (*arr[2])() = { a, b};
arr[0](); // calls foo
arr[1](); //calls foo1
return 0;
}
Method 1 can be executed here.
Method 2
#include <iostream>
void foo()
{
std::cout << "Hello";
}
void foo2()
{
std::cout << " wolrd!";
}
int main()
{
//create array(of size 2) that can hold pointers to functions that does not return anything
void (*arr[2])() = { foo, foo2};
arr[0](); // calls foo
arr[1](); //calls foo1
return 0;
}
Method 2 can be executed here.
Related
How to read the following code for main?
I do not know this
Code :
class one
{
public:
void operator()() const
{
f();
f1();
}
};
I want to call the operator To main?
void operator()() const defines a function call operator, which can be used as:
one ob;
ob(); // calls ob.operator()()
For another, more complete, example.
#include <iostream>
class Two
{
public:
int operator()(const char *str) const
{
std::cout << "operator() called with " << str << std::endl;
return 101;
}
};
int main()
{
Two two;
int n = two("'test'");
std::cout << "operator() returned " << n << std::endl;
}
Output:
operator() called with 'test'
operator() returned 101
You can create an instance of the class in the main function and call the function using that instance.
class one
{
public:
void operator()() const
{
f();
f1();
}
};
int main() {
one obj_one;
// calling the member function -> method
obj_one.operator()();
return 0;
}
When I try to compile the following code in gcc 4.8.2, I get the following error:
test.cc: In function ‘void foo(int*)’:
test.cc:15:16: error: no matching function for call to ‘begin(int*&)’
for (int i : bar) {
^
Along with a bunch of others from deeper in the template library.
#include <iostream>
using namespace std;
void foo(int*);
int main() {
int bar[3] = {1,2,3};
for (int i : bar) {
cout << i << endl;
}
foo(bar);
}
void foo(int* bar) {
for (int i : bar) {
cout << i << endl;
}
}
If I redefine foo to use an indexed for loop, then the code compiles and behaves as expected. Also, if I move the range-based output loop into main, I get the expected behaviour as well.
How do I pass the array bar to foo in such a way that it is capable of executing a range-based for-loop on it?
With the array decaying into a pointer you're losing one important piece of information: its size.
With an array reference your range based loop works:
void foo(int (&bar)[3]);
int main() {
int bar[3] = {1,2,3};
for (int i : bar) {
cout << i << endl;
}
foo(bar);
}
void foo(int (&bar)[3]) {
for (int i : bar) {
cout << i << endl;
}
}
or, in a generic fashion (i.e. without specifying the array size in the function signature),
template <std::size_t array_size>
void foo(int (&bar)[array_size]) {
for (int i : bar) {
cout << i << endl;
}
}
Try it out
For a fixed size array you can
Pass a raw array by reference.
Pass a std::array by reference.
Pass a std::vector by reference.
The natural choice (for a fixed size array) is std::array, i.e.
#include <iostream>
#include <array>
using namespace std;
void foo(array<int, 3> const& bar) {
for (int i : bar) {
cout << i << endl;
}
}
int main() {
array<int,3> const bar = {1,2,3};
for (int i : bar) {
cout << i << endl;
}
foo(bar);
}
Using C++20's std::span, you can have a reference to an array or runtime size.
Here's your code with std::span instead:
#include <iostream>
#include <span>
void foo(std::span<int>);
int main() {
int bar[3] = {1,2,3};
for (int i : bar) {
std::cout << i << std::endl;
}
foo(bar);
}
void foo(std::span<int> bar) {
for (int i : bar) { // now works
std::cout << i << std::endl;
}
}
In C ++, I first encountered function pointers.
I tried to use this to make it similar to Action and Delegate in C #.
However, when declaring a function pointer, it is necessary to specify the type of the class in which the function exists.
ex) void (A :: * F) ();
Can I use a function pointer that can store a member function of any class?
In general, function pointers are used as shown in the code below.
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(A::*BF)();
};
int main()
{
A a;
B b;
b.BF = &A::AF;
(a.*b.BF)();
return 0;
}
I want to use it like the code below.
is this possible?
Or is there something else to replace the function pointer?
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(* BF)();
};
int main()
{
A a;
B b;
b.BF = a.AF;
return 0;
}
I solved the question through the answer.
Thanks!
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class C {
public:
void CF() { std::cout << "C::F" << std::endl; }
};
class B {
public:
B(){}
std::function<void()> BF;
};
int main() {
A a;
C c;
B b;
b.BF = std::bind(&A::AF, &a);
b.BF();
b.BF = std::bind(&C::CF, &c);
b.BF();
int i;
std::cin >> i;
return 0;
}
What you want to do is probably something like this. You can use std::function to hold a pointer to a member function bound to a specific instance.
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class B {
public:
B(const std::function<void()>& bf) : BF(bf) {}
std::function<void()> BF;
};
int main() {
A a;
B b1(std::bind(&A::AF, &a)); // using std::bind
B b2([&a] { a.AF(); }); // using a lambda
b1.BF();
b2.BF();
return 0;
}
Here's a C# style implementation of the accepted answer, It is memory efficient and flexible as you can construct and delegate at different points of execution which a C# developer might expect to do:
#include <iostream>
#include <functional>
using namespace std;
class A {
public:
void AF() { cout << "A::F" << endl; }
void BF() { cout << "B::F" << endl; }
};
class B {
public:
std::function<void()> Delegate;
};
int main() {
A a;
B b;
b.Delegate = std::bind(&A::AF, &a);
b.Delegate();
b.Delegate = [&a] { a.BF(); };
b.Delegate();
return 0;
}
I'm trying to pass a reference to a function in a class but am having trouble figuring out how to do it. So say I have a class test defined as such
#include <iostream>
class test {
public:
test () {};
~test () {};
void setA (int);
int getA (void);
private:
int a;
};
void test::setA (int A) { a = A; }
int test::getA (void) { return a; }
using namespace std;
int main ()
{
test T;
T.setA(5);
cout << "a = " << T.getA() << endl;
return 0;
}
That works fine but if I want to pass the values by reference
#include <iostream>
class test {
public:
test () {};
~test () {};
void setA (int);
int & getA (void);
private:
int a;
};
void test::setA (int & A) { a = A; }
int & test::getA (void) { return a; }
using namespace std;
int main ()
{
test T;
T.setA(5);
cout << "a = " << T.getA() << endl;
return 0;
}
I cannot figure out how to configure setA to pass by reference.
There are two issues with the code. First, the definition of setA does not match the declaration. You must make the declaration take in a reference as a parameter.
Change this:
void setA (int);
To this:
void setA (int&);
The second issue is that you are trying to pass an r-value (5) as a reference. You must pass in an l-value. You can do that by creating an int first and then passing that by reference:
int i = 5;
T.setA(i);
Full example:
#include <iostream>
class test {
public:
test () {};
~test () {};
void setA (int&);
int & getA (void);
private:
int a;
};
void test::setA (int & A) { a = A; }
int & test::getA (void) { return a; }
using namespace std;
int main ()
{
test T;
int i = 5;
T.setA(i);
cout << "a = " << T.getA() << endl;
return 0;
}
When you pass something by reference to a function in C++, the function does not keep the parameter in memory automatically. Thus, you have to declare it before so that it stays in memory throughout the entire function.
The 5 you tried to pass as a reference would go out of scope and get destroyed as soon as the function starts. The declared i variable is instead destroyed at the end of the main function.
The reason is because in order to pass by reference, you must have an lvalue, which is a fancy way of saying something that persists beyond a single use.
If you created an int variable, you would be able to pass it in by reference. In the code above, you attempted to pass in a raw integer value (5), which fails, since the compiler is expecting a reference to an int, not a raw integer value.
The following code would work:
int main ()
{
test T;
int myVariable = 4; // Need an actual variable to pass by reference.
T.setA(myVariable);
cout << "a = " << T.getA() << endl;
return 0;
}
However, if you want your function to take raw integer values like you showed in your second example, you must have a function definition like your first example, where all the function takes is an integer. Hope this helps!
Maybe you could try this:
#include <iostream>
class test {
public:
test() {};
~test() {};
void setA(int&&); // requires at least C++11
void setA(int&);
int & getA(void);
private:
int a;
};
void test::setA(int && A) { a = A; }
void test::setA(int&A) { a = A; }
int & test::getA(void) { return a; }
using namespace std;
int main()
{
test T;
int i = 5;
T.setA(i);
cout << "a = " << T.getA() << endl;
T.setA(8);
cout << "a = " << T.getA() << endl;
return 0;
}
In the example, int& passes a l-value while int&& passes a r-value as a reference.
When I try to compile the following code in gcc 4.8.2, I get the following error:
test.cc: In function ‘void foo(int*)’:
test.cc:15:16: error: no matching function for call to ‘begin(int*&)’
for (int i : bar) {
^
Along with a bunch of others from deeper in the template library.
#include <iostream>
using namespace std;
void foo(int*);
int main() {
int bar[3] = {1,2,3};
for (int i : bar) {
cout << i << endl;
}
foo(bar);
}
void foo(int* bar) {
for (int i : bar) {
cout << i << endl;
}
}
If I redefine foo to use an indexed for loop, then the code compiles and behaves as expected. Also, if I move the range-based output loop into main, I get the expected behaviour as well.
How do I pass the array bar to foo in such a way that it is capable of executing a range-based for-loop on it?
With the array decaying into a pointer you're losing one important piece of information: its size.
With an array reference your range based loop works:
void foo(int (&bar)[3]);
int main() {
int bar[3] = {1,2,3};
for (int i : bar) {
cout << i << endl;
}
foo(bar);
}
void foo(int (&bar)[3]) {
for (int i : bar) {
cout << i << endl;
}
}
or, in a generic fashion (i.e. without specifying the array size in the function signature),
template <std::size_t array_size>
void foo(int (&bar)[array_size]) {
for (int i : bar) {
cout << i << endl;
}
}
Try it out
For a fixed size array you can
Pass a raw array by reference.
Pass a std::array by reference.
Pass a std::vector by reference.
The natural choice (for a fixed size array) is std::array, i.e.
#include <iostream>
#include <array>
using namespace std;
void foo(array<int, 3> const& bar) {
for (int i : bar) {
cout << i << endl;
}
}
int main() {
array<int,3> const bar = {1,2,3};
for (int i : bar) {
cout << i << endl;
}
foo(bar);
}
Using C++20's std::span, you can have a reference to an array or runtime size.
Here's your code with std::span instead:
#include <iostream>
#include <span>
void foo(std::span<int>);
int main() {
int bar[3] = {1,2,3};
for (int i : bar) {
std::cout << i << std::endl;
}
foo(bar);
}
void foo(std::span<int> bar) {
for (int i : bar) { // now works
std::cout << i << std::endl;
}
}