I am trying to do set a void function in c++ inside another void. I was instructed to use this non-functioning code:
void function() {
log("Original function")
}
int main(){
function = []()
{
log("New Function");
};
}
and get this :
error: invalid use of member function ‘void function()’ (did you forget the ‘()’ ?).
Can anyone help? Is this even possible and if not then can anyone provide an alternative? All help is approved.
I think you want function to be a function pointer, not a function.
So maybe something a little like this:
void (*function)();
int main(){
function = []()
{
log("New Function");
};
return 0;
}
Function definitions cannot be changed at runtime like this, so you will need to use some sort rebindable object that is invocable instead.
If your lambda is never going to capture a value, then you can use function pointers for this purpose -- since a non-capturing lambda can be converted to a function pointer. For example:
using function_t = void(*)();
void function_default() {
log("Original function");
}
function_t function = &function_default;
int main() {
function = []{
log("New Function");
};
}
Try it Online
However, be aware that as soon as you want to capture data in that lambda, this will not work. At which point you'll be better off using something like std::function which can work with any invocable object:
using function_t = std::function<void()>;
void function_default() {
log("Original function");
}
function_t function = &function_default;
int main() {
int some_value = 5;
function = [=]{
log("New Function with value = " + std::to_string(some_value));
};
}
Try it Online
To answer your question, yes, you can do this, but it will require the usage of a lambda function:
void main()
{
auto func = []()-> void // Note: This is a lambda function.
{
// Code...
};
// If you want to run "func" call it in your void, if not, leave it uncalled.
func();
}
For more information on lambdas, I'll provide a link here.
Related
I need to call a function when a button is pressed. The following function should take in the function to be called:
void ButtonLayer::LoadButton(void(*func)()) {
// do button loading stuff
// if button is clicked...
func();
}
This would work except for the fact that passing a function within a seperate namespace gives the following error:
argument of type "void(OtherLayer::*)()" is incompatiable with parameter of type "void(*)()"
I don't want to make every function I pass static to avoid this problem, so I need some way of converting a function within a namespace to be of type void(*). I have tried static casting but I'm unsure of the exact syntax as I'm new to C++
It seems that you want to pass a member function.
This example may help you.
class A {
public:
int i;
int fun(int j) {
return i + j;
};
};
void fun(int j, A ob, int (A::* p)(int)) {
std::cout << (ob.*p)(j);
}
void main() {
int (A:: * fp)(int); //declare fp as a function pointer in class A
fp = &A::fun; //init fp
A obj;
obj.i = 1;
fun(123, obj, fp);
}
Based on #Yksisarvinen and #MSalters comments, the solution was:
void ButtonLayer::LoadButton(std::function<void()>) {
// do button loading stuff
// if button is clicked...
func();
}
and then to call it:
LoadButton([this] { functionToCall; });
I want to have objects with one method which calls a function (but every object should have a different function to call). I will try to show you what I mean by showing an example:
class Human
{
public:
void setMyFunction(void func); // specify which function to call
void callMyFunction(); // Call the specified function
};
void Human::setMyFunction(void func) // ''
{
myFunction = func;
}
void Human::callMyFunction() // ''
{
myFunction();
}
void someRandomFunction() // A random function
{
// Some random code
}
int main()
{
Human Lisa; // Create Object
Lisa.setMyFunction(); // Set the function for that object
Lisa.callMyFunction(); // Call the function specified earlier
}
This code (obviously) doesn't work but I hope you understand what I am trying to accomplish.
MfG, TPRammus
You might use std::function.
#include <functional>
class Human
{
std::function<void()> mFunc;
public:
void setMyFunction(std::function<void()> func) { mFunc = func; }
void callMyFunction() { if (mFunc) mFunc(); }
};
Demo
I would suggest using a simple function pointer. Just do this:
class Human
{
public:
using func_t = void (*)();
void setMyFunction(func_t f) {
func = f;
}
void callMyFunction() {
func();
}
private:
func_t func;
};
The reasons why one might prefer function pointers to std::function are:
Performance. Calling std::function tends to be slower, than calling a function by pointer.
std::function needs truly ugly syntax when one needs to bind it to an overloaded function.
Example:
void foo();
void foo(int x = 0);
void check() {
Human h;
h.setMyFunction(&foo);
}
Will fail to compile.
I am not sure whether the following is possible. Can someone give an equivalent for this requirement?
if(dimension==2)
function = function2D();
else if(dimension==3)
function = function3D();
for(....) {
function();
}
It is possible, assuming two things:
Both function2D() and function3D() have the same signature and return type.
function is a function pointer, with the same return type and parameters as both function2D and function3D.
The technique you are exploring is very similar to the one used in constructing a jump table. You have a function pointer, which you assign (and call through) at run-time based on run-time conditions.
Here is an example:
int function2D()
{
// ...
}
int function3D()
{
// ...
}
int main()
{
int (*function)(); // Declaration of a pointer named 'function', which is a function pointer. The pointer points to a function returning an 'int' and takes no parameters.
// ...
if(dimension==2)
function = function2D; // note no parens here. We want the address of the function -- not to call the function
else if(dimension==3)
function = function3D;
for (...)
{
function();
}
}
You can use function pointers.
There's a tutorial here but basically what you do is declare it like this:
void (*foo)(int);
where the function has one integer argument.
Then you call it like this:
void my_int_func(int x)
{
printf( "%d\n", x );
}
int main()
{
void (*foo)(int);
foo = &my_int_func;
/* call my_int_func (note that you do not need to write (*foo)(2) ) */
foo( 2 );
/* but if you want to, you may */
(*foo)( 2 );
return 0;
}
So as long as your functions have the same number and type of argument you should be able to do what you want.
Since this is also tagged C++, you can use std::function if you have access to C++11, or std::tr1::function if your compiler supports C++98/03 and TR1.
int function2d();
int function3D();
int main() {
std::function<int (void)> f; // replace this with the signature you require.
if (dimension == 2)
f = function2D;
else if (dimension == 3)
f = function3D;
int result = f(); // Call the function.
}
As mentioned in the other answers, make sure your functions have the same signature and all will be well.
If your compiler doesn't offer std::function or std::tr1::function, there's always the boost library.
Since you choose C++
Here's with std::function example in C++11
#include <functional>
#include <iostream>
int function2D( void )
{
// ...
}
int function3D( void )
{
// ...
}
int main()
{
std::function<int(void)> fun = function2D;
fun();
}
I have to make some kind of bridge between two pieces of software, but am facing an issue I don't know how to deal with. Hopefully someone will have interesting and (preferably) working suggestions.
Here is the background : I have a C++ software suite. I have to replace some function within a given class with another function, which is ok. The problem is that the new function calls another function which has to be static, but has to deal with members of the class. This is this second function which is making me mad.
If the function is not static I get the following error :
error: argument of type ‘void (MyClass::)(…)’ does not match ‘void (*)(…)’
If I set it to static I get either the following error :
error: cannot call member function ‘void
MyClass::MyFunction(const double *)’ without object
or
error: ‘this’ is unavailable for static member functions
depending on if I use or not the "this" keyword ("Function()" or "this->Function()").
And finally, the class object requires some arguments which I cannot pass to the static function (I cannot modify the static function prototype), which prevents me to create a new instance within the static function itself.
How would you deal with such a case with minimal rewriting ?
Edit : Ok, here is a simplified sample on what I have to do, hoping it is clear and correct :
// This function is called by another class on an instance of MyClass
MyClass::BigFunction()
{
…
// Call of a function from an external piece of code,
// which prototype I cannot change
XFunction(fcn, some more args);
…
}
// This function has to be static and I cannot change its prototype,
// for it to be passed to XFunction. XFunction makes iterations on it
// changing parameters (likelihood maximization) which do not appear
// on this sample
void MyClass::fcn(some args, typeN& result)
{
// doesn't work because fcn is static
result = SomeComputation();
// doesn't work, for the same reason
result = this->SomeComputation();
// doesn't work either, because MyClass has many parameters
// which have to be set
MyClass *tmp = new MyClass();
result = tmp->SomeComputation();
}
Pointers to non-static member functions are a bit tricky to deal with. The simplest workaround would just be to add an opaque pointer argument to your function which you can then cast as a pointer to 'this', then do what you need with it.
Here's a very simple example:
void doSomething(int (*callback)(void *usrPtr), void *usrPtr)
{
// Do stuff...
int value = callback(usrPtr);
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(myCallback, this);
}
private:
int value_;
static int myCallback(void *usrPtr)
{
MyClass *parent = static_cast<MyClass *>(usrPtr);
return parent->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
In this example myCallback() can access the private value_ through the opaque pointer.
If you want a more C++-like approach you could look into using Boost.Function and Boost.Bind which allow you to pass non-static member functions as callbacks:
void doSomething(boost::function<int ()> callback)
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(boost::bind(&MyClass::myCallback, this));
}
private:
int value_;
int myCallback()
{
return value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
If you really can't change the function prototype you could use a global pointer, but that opens up all sorts of issues if you will ever have more than one instance of your class. It's just generally bad practice.
class MyClass;
static MyClass *myClass;
void doSomething(int (*callback)())
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
myClass = this;
doSomething(myCallback);
}
private:
int value_;
static int myCallback()
{
return myClass->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
Following spencercw's suggestion below the initial question I tried the "static member variable that you set to point to this" solution (the global variable would have been tricky and dangerous within the context of the software suite).
Actually I figured out there was already something like this implemented in the code (which I didn't write) :
static void* currentObject;
So I just used it, as
((MyClass*)currentObject)->SomeComputation();
It does work, thanks !!!
non-reentrant and non-thread-safe way is to pass "this" address using global variable.
You can move the result = SomeComputation(); out of your static function and place it in BigFunction right before your call to the static function.
Suppose I have a class with 2 static functions:
class CommandHandler
{
public:
static void command_one(Item);
static void command_two(Item);
};
I have a DRY problem where I have 2 functions that have the exact same code for every single line, except for the function that it calls:
void CommandOne_User()
{
// some code A
CommandHandler::command_one(item);
// some code B
}
void CommandTwo_User()
{
// some code A
CommandHandler::command_two(item);
// some code B
}
I would like to remove duplication, and, ideally, do something like this:
void CommandOne_User()
{
Function func = CommandHandler::command_one();
Refactored_CommandUser(func);
}
void CommandTwo_User()
{
Function func = CommandHandler::command_one();
Refactored_CommandUser(func);
}
void Refactored_CommandUser(Function func)
{
// some code A
func(item);
}
I have access to Qt, but not Boost. Could someone help suggest a way on how I can refactor something like this?
You could use function pointers:
// type of the functions
typedef void Function(Item);
void CommandOne_User() {
// function pointer
Function *func = CommandHandler::command_one;
Refactored_CommandUser(func);
}
void CommandTwo_User() {
// can also be used directly, without a intermediate variable
Refactored_CommandUser(CommandHandler::command_two);
}
// taking a function pointer for the command that should be executed
void Refactored_CommandUser(Function *func) {
// calling the funcion (no explicit dereferencing needed, this conversion is
// done automatically)
func(item);
}
Besides the C way (passing a function pointer) or the C++ way mentioned by Jay here there is the other (modern) c++ way with boost or with a compiler with c++0x support:
void Refactored_CommandUser( boost::function<void (Item)> f ) {
// alternatively std::function with proper compiler support
}
With the advantage that this encapsulates a functor, and can be combined with boost::bind (or std::bind) to pass in not only free-function pointers that match the signature exactly, but also other things, like member pointers with an object:
struct test {
void f( Item );
};
void foo( Item i, std::string const & caller );
void bar( Item i );
int main() {
test t;
Refactored_CommandUser( boost::bind( &test::f, &t, _1 ) );
Refactored_CommandUser( boost::bind( foo, _1, "main" ) );
Refactored_CommandUser( bar ); // of course you can pass a function that matches directly
}
I posted a question very similar to this and this was the explanation I got:
Function Pointers
And here is the link to the question I posted: Function callers (callbacks) in C?
Another way to do this if you don't have access to tr1 or boost, is just to use function template. It's quite simple and obviously a C++ way.
Here's a compilable example similar to yours:
#include <iostream>
using namespace std;
class CommandHandler
{
public:
static void command_one(int i) { cout << "command_one " << i << endl; }
static void command_two(int i) { cout << "command_two " << i << endl; }
};
template <typename Func>
void CommandCaller(Func f)
{
f(1);
}
int main()
{
CommandCaller(&CommandHandler::command_one);
return 0;
}
I can think of two ways.
The C style way: pass the function to be called in as a function pointer.
The C++ way: create a base class that implements your code and replace the called function with a virtual method. Then derive two concrete classes from the base class, each one implementing the virtual function differently.
see this please
http://www.newty.de/fpt/fpt.html
Static member functions can be passed simply as function pointers.
Non-static can be passed as member-function pointer + this.
void Refactored_CommandUser(static void (*func)(Item))
{
// some code A
func(item);
// some code B
}
void CommandOne_User()
{
Refactored_CommandUser(&CommandHandler::command_one);
}
void CommandTwo_User()
{
Refactored_CommandUser(&CommandHandler::command_two);
}
So inspired by David Roriguez's answer, I tried it out on my own and, yup, it works:
Here's an example (stupid) code of the "modern" way to pass a function as a function parameter:
#include <functional>
#include <assert.h>
class Command
{
public:
static int getSeven(int number_)
{
return 7 + number_;
}
static int getEight(int number_)
{
return 8 - number_;
}
};
int func(std::tr1::function<int (int)> f, int const number_ )
{
int const new_number = number_ * 2;
int const mod_number = f(new_number);
return mod_number - 3;
}
int main()
{
assert( func(Command::getSeven, 5) == 14 );
assert( func(Command::getEight, 10) == -15 );
return 0;
}
I tried this on VS2008 with Intel C++ Compiler 11.1 with C++0X support on (don't know if C++0x support is really needed since it's in TR1).