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
Related
In this code I want to call second function (with reference argument). How I can do this? This is even possible?
void g(int){ std::cout << 1; }
void g(int&){ std::cout << 2; }
int main() {
int i = 42;
g( i ); // want to output "2"
}
Do you want to have 1 when calling g(42) and 2 when calling g(i)?
Then you should change the prototype of the first function to get a const int &:
#include <iostream>
void g(const int&){ std::cout << 1; }
void g(int&){ std::cout << 2; }
int main() {
int i = 42;
g( i ); // want to output "2"
}
For g(i) the int & is a better fit than the const int &, so it will call the second.
You can't do it exactly like that. To overload functions, at least one of the arguments needs to be of a different type, or have a different number of arguments (see: https://www.cplusplus.com/doc/tutorial/functions2/). You could achieve something similiar, but rather unadvisable like this:
#include <iostream>
void g(int){ std::cout << 1; }
void g(long int&){ std::cout << 2; }
int main() {
int i = 42;
g(i); // outputs 1
long int i = 42;
g(i); // outputs 2
}
You can also get more information on function overloading here
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'
In my project, there are a few lines in a MyClass.h file
class MyClass{
public:
....
#ifndef __MAKECINT__
std::vector<Status_e(MyClass::*)(TupleInfo & info)> m_processObjects; //!
#endif
....
}
//The Status_e is an enum type
//The TupleInfo is a struct
I can't understand what the usage of this * in above code snippet. And in the MyClass.cxx file, the m_processObjects used as this:
for (unsigned int f = 0; f < m_processObjects.size(); ++f) {
status = (this->*m_processObjects[f])( m_tuples[i] );
if ( status == FAILURE ) {
return EL::StatusCode::FAILURE;
}
....
}
....
I have never heard about the usage like this->*blabla, but this code snippet works. So what it means?
::* denotes a Pointer to member.
With the surrounding code it's actually a Pointer to member function.
Status_e(MyClass::*)(TupleInfo & info)
is a member function of class MyClass, returning Status_e, and having one parameter TupleInfo&. (The argument name info is useless here but obviously silently ignored by the compiler.)
The other snippet in OP's question shows how to call it:
status = (this->*m_processObjects[f])(m_tuples[i]);
Storing a method pointer would look like this:
std::vector<Status_e(MyClass::*)(TupleInfo & info)> m_processObjects;
...
m_processObjects.push_back(&MyClass::aMethod);
Of course, the signature of MyClass::aMethod must match.
A simplified sample to demonstrate it:
#include <iostream>
#include <vector>
class Test {
private:
std::vector<int(Test::*)(const char*)> _tblTestFuncs;
public:
Test()
{
_tblTestFuncs.push_back(&Test::func1);
_tblTestFuncs.push_back(&Test::func2);
_tblTestFuncs.push_back(&Test::func3);
}
int func1(const char *caller) { std::cout << "Test::func1 called from '"<< caller << "': "; return 1; }
int func2(const char *caller) { std::cout << "Test::func2 called from '"<< caller << "': "; return 2; }
int func3(const char *caller) { std::cout << "Test::func3 called from '"<< caller << "': "; return 3; }
void call()
{
for (size_t i = 0, n = _tblTestFuncs.size(); i < n; ++i) {
int result = (this->*_tblTestFuncs[i])("Test::call()");
std::cout << "Return: " << result << '\n';
}
}
};
int main()
{
Test test;
// test method vector in main()
std::vector<int(Test::*)(const char*)> tblTestFuncs;
tblTestFuncs.push_back(&Test::func1);
tblTestFuncs.push_back(&Test::func2);
tblTestFuncs.push_back(&Test::func3);
for (size_t i = 0, n = tblTestFuncs.size(); i < n; ++i) {
int result = (test.*tblTestFuncs[i])("main()");
std::cout << "Return: " << result << '\n';
}
// test method vector in Test
test.call();
// done
return 0;
}
Output:
Test::func1 called from 'main()': Return: 1
Test::func2 called from 'main()': Return: 2
Test::func3 called from 'main()': Return: 3
Test::func1 called from 'Test::call()': Return: 1
Test::func2 called from 'Test::call()': Return: 2
Test::func3 called from 'Test::call()': Return: 3
Live Demo on coliru.com
In my project, there are a few lines in a MyClass.h file
class MyClass{
public:
....
#ifndef __MAKECINT__
std::vector<Status_e(MyClass::*)(TupleInfo & info)> m_processObjects; //!
#endif
....
}
//The Status_e is an enum type
//The TupleInfo is a struct
I can't understand what the usage of this * in above code snippet. And in the MyClass.cxx file, the m_processObjects used as this:
for (unsigned int f = 0; f < m_processObjects.size(); ++f) {
status = (this->*m_processObjects[f])( m_tuples[i] );
if ( status == FAILURE ) {
return EL::StatusCode::FAILURE;
}
....
}
....
I have never heard about the usage like this->*blabla, but this code snippet works. So what it means?
::* denotes a Pointer to member.
With the surrounding code it's actually a Pointer to member function.
Status_e(MyClass::*)(TupleInfo & info)
is a member function of class MyClass, returning Status_e, and having one parameter TupleInfo&. (The argument name info is useless here but obviously silently ignored by the compiler.)
The other snippet in OP's question shows how to call it:
status = (this->*m_processObjects[f])(m_tuples[i]);
Storing a method pointer would look like this:
std::vector<Status_e(MyClass::*)(TupleInfo & info)> m_processObjects;
...
m_processObjects.push_back(&MyClass::aMethod);
Of course, the signature of MyClass::aMethod must match.
A simplified sample to demonstrate it:
#include <iostream>
#include <vector>
class Test {
private:
std::vector<int(Test::*)(const char*)> _tblTestFuncs;
public:
Test()
{
_tblTestFuncs.push_back(&Test::func1);
_tblTestFuncs.push_back(&Test::func2);
_tblTestFuncs.push_back(&Test::func3);
}
int func1(const char *caller) { std::cout << "Test::func1 called from '"<< caller << "': "; return 1; }
int func2(const char *caller) { std::cout << "Test::func2 called from '"<< caller << "': "; return 2; }
int func3(const char *caller) { std::cout << "Test::func3 called from '"<< caller << "': "; return 3; }
void call()
{
for (size_t i = 0, n = _tblTestFuncs.size(); i < n; ++i) {
int result = (this->*_tblTestFuncs[i])("Test::call()");
std::cout << "Return: " << result << '\n';
}
}
};
int main()
{
Test test;
// test method vector in main()
std::vector<int(Test::*)(const char*)> tblTestFuncs;
tblTestFuncs.push_back(&Test::func1);
tblTestFuncs.push_back(&Test::func2);
tblTestFuncs.push_back(&Test::func3);
for (size_t i = 0, n = tblTestFuncs.size(); i < n; ++i) {
int result = (test.*tblTestFuncs[i])("main()");
std::cout << "Return: " << result << '\n';
}
// test method vector in Test
test.call();
// done
return 0;
}
Output:
Test::func1 called from 'main()': Return: 1
Test::func2 called from 'main()': Return: 2
Test::func3 called from 'main()': Return: 3
Test::func1 called from 'Test::call()': Return: 1
Test::func2 called from 'Test::call()': Return: 2
Test::func3 called from 'Test::call()': Return: 3
Live Demo on coliru.com
I have a macro that implements a retry mechanism that looks like that:
#define RETRY(function_name, param_list, max_attempts, retry_interval_usecs, error_var) \
do { \
int _attempt_; \
\
for (_attempt_ = 0; _attempt_ < max_attempts; _attempt_++) \
{ \
error_var = function_name param_list; \
if (error_var == SUCCESS) \
{ \
break; \
} \
\
usleep(retry_interval_usecs); \
} \
} while (0)
This is functional, but I keep hearing that within a C++ application, defines are not favorable.
Now I looked into a retry function that takes a function pointer as an argument. But I seem to have missed something since I can't get this code to compile.
Note: This code below is NON-Functional, I thought I can post a simple code to illustrate what I want to do:
void retry(int (*pt2Func)(void* args))
{
const int numOfRetries = 3;
int i = 1;
do
{
//Invoke the function that was passed as argument
if((*pt2Func)(args)) //COMPILER: 'args' was not declared in this scope
{
//Invocation is successful
cout << "\t try number#" << i <<" Successful \n";
break;
}
//Invocation is Not successful
cout << "\t try number#" << i <<" Not Successful \n";
++i;
if (i == 4)
{
cout<< "\t failed invocation!";
}
}while (i <= numOfRetries);
}
int Permit(int i)
{
//Permit succeeds the second retry
static int x = 0;
x++;
if (x == 2 && i ==1 ) return 1;
else return 0;
}
int main()
{
int i = 1;
int * args = &i;
retry(&Permit(args));
}
So Basically my question is:
How can I pass a general function with different parameter (in type and number) to the retry method? without encapsulating the functions within a class?
Is that doable?
All existing answers are C++11, so here's a minor modification to your code to make it work using boost (which is C++03)
//takes any function or function like object
//expected function takes no parameters and returns a bool
template<class function_type>
void retry(function_type function, int numOfRetries = 3)
{
int i = 1;
do
{
//Invoke the function that was passed as argument
if(function())
blah blah blah
and in main
int main()
{
int i = 1;
//bind takes a function and some parameters
//and returns a function-like object with a different parameter set
//in this case, the function Permit, and the first thing it gets passed is i
//this means the resulting function-like object doesn't need any parameters
//return type is the same as the original function
retry(boost::bind(Permit, i));
}
Proof of C++03 compilation and execution
The following solution uses C++11 features - the addition that it is not possible to use C++11 was done after the development of the solution started.
One C++ way is using std::function.
The following code gives examples for function, 'callable' classes and lambda expressions.
#include <string>
#include <iostream>
#include <functional>
#include <unistd.h>
// Minimalistic retry
bool retry( std::function<bool()> func, size_t max_attempts,
unsigned long retry_interval_usecs ) {
for( size_t attempt { 0 }; attempt < max_attempts; ++attempt ) {
if( func() ) { return true; }
usleep( retry_interval_usecs );
}
return false;
}
// Ex1: function
int f(std::string const u) {
std::cout << "f()" << std::endl;
return false;
}
// Ex2: 'callable' class
struct A {
bool operator() (std::string const & u, int z) {
++m_cnt;
std::cout << "A::op() " << u << ", " << z << std::endl;
if( m_cnt > 3 ) {
return true;
}
return false;
}
int m_cnt { 0 };
};
int main() {
A a;
bool const r1 = retry( std::bind(f, "stringparam1"), 3, 100 );
bool const r2 = retry( std::bind(a, "stringparam2", 77), 5, 300 );
// Ex 3: lambda
bool const r3 = retry( []() -> bool
{ std::cout << "lambda()" << std::endl; return false; }, 5, 1000 );
std::cout << "Results: " << r1 << ", " << r2 << ", " << r3 << std::endl;
return 0;
}
Tested this with gcc 4.7.2. Output:
f()
f()
f()
A::op() stringparam2, 77
A::op() stringparam2, 77
A::op() stringparam2, 77
A::op() stringparam2, 77
lambda()
lambda()
lambda()
lambda()
lambda()
Results: 0, 1, 0
There are two ways.
Using a variadic template function:
// All in header file:
template <typename F, typename... Args>
void retry1(F func, Args&& ... args) {
//...
if (func(std::forward<Args>(args)...))
; //...
}
// Call like:
retry1(Permit, i);
Or using a std::function and a lambda:
// In header file
void retry2(std::function<bool()> func);
// In a source file
void retry2(std::function<bool()> func) {
//...
if (func())
; //...
}
// Call like:
retry2([]() -> bool { return Permit(i); });
FWIW, i'm trying to fix your initial exmaple. (There may be other drawbacks, and no one will go this way, since there are better solutions)
Your initial definition for retry can be written as:
void retry(int (*pt2Func)(void* args), void* args)
It gets a function pointer (to a function returning and int and a void* argument) and an additional (void*) argument.
The Permit function is now:
int Permit(void* pvi)
The main function now calls the retry/Permit as follows:
retry(&Permit, static_cast<void*>(args));
Complete example
#include <iostream>
using std::cout;
void retry(int (*pt2Func)(void* args), void* args)
{
const int numOfRetries = 3;
int i = 1;
do
{
//Invoke the function that was passed as argument
if((*pt2Func)(args)) //not changed: args is now declared
{
//Invocation is successful
cout << "\t try number#" << i <<" Successful \n";
break;
}
//Invocation is Not successful
cout << "\t try number#" << i <<" Not Successful \n";
++i;
if (i == 4)
{
cout<< "\t failed invocation!";
}
}while (i <= numOfRetries);
}
int Permit(void* pvi)
{
//Permit succeeds the second retry
int i = *(static_cast<int*>(pvi));
static int x = 0;
x++;
if (x == 2 && i ==1 ) return 1;
else return 0;
}
int main()
{
int i = 1;
int * args = &i;
retry(&Permit, static_cast<void*>(args));
}
Well, if you're using C++11, you have Lambda Expressions.
There's also this question: Write a function that accepts a lambda expression as argument that provides another relevant example.
EDIT after seeing you can't use C++11
In that case, I'd just keep the macro and forget about it. While some people might frown upon it, you have a good reason to use it - it's easier and makes more sense than another solution. Just write that in a comment above the macro, so that 5 years from now when people try to figure out why you decided not to use std:forward or lambda expressions, they'll know.