Is it possible to equate a function name to another function name? - c++

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

Related

Set a void function inside another function

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.

How do I pass a function within a namespace as a non-namespace parameter?

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

Having the same member function have different definitions for different class instances

Is it possible for the same member function to have different definitions for different objects of that class?
IMPORTANT NOTE: I cannot use a callback like in this solution. (reason explained below example)
Lets say we have this object:
struct object
{
int n;
int m;
void f();
};
Is it possible to have something like:
object a,b;
// and here to define the functions
a.f() {std::cout << n+m;}
b.f() {std::cout << n-m;}
The reason i cannot use a callback is because the function i want to define will be recursive and will overflow. What i am trying to do with this method is to create an immitation of the stack (but all the variables are stored on heap as a double chained list) and so i will call a void (void) function that has no local variables thus increasing the stack depth the function can achieve. Also important to mention is that i want to make a header file with this idea. For further context explination, this is how it should work:
MyHeader.h
template <typename PARAM_TYPE> class HEAP_FUNCTION
{
private:
struct THIS_CALL // ! THIS HAS NOTHING TO DO WITH THE __thiscall CALLING CONVENTION !
{
PARAM_TYPE* PARAM;
THIS_CALL* next_call;
THIS_CALL* prev_call;
};
THIS_CALL* FIRST_CALL;
THIS_CALL* CURRENT_CALL;
public:
HEAP_FUNCTION(PARAM_TYPE* FirstCall)
{
FIRST_CALL = new THIS_CALL;
CURRENT_CALL = FIRST_CALL;
FIRST_CALL->PARAM = *FirstCall;
}
HEAP_FUNCTION(PARAM_TYPE FirstCall)
{
FIRST_CALL = new THIS_CALL;
CURRENT_CALL = FIRST_CALL;
FIRST_CALL->PARAM = FirstCall;
}
~HEAP_FUNCTION()
{
delete FIRST_CALL;
}
void call(void);
};
Source.cpp
// This is the ilustration of the recursive method for calculating
// the 1+2+3+...+n sum.
// The "normal" definition for this function would be:
//
// unsigned long long sum(unsigned long long n)
// {
// if (n == 0) return 0;
// return n + sum(n-1);
// }
//
// The function presented bellow is the equivalent.
struct Param
{
unsigned long long n;
unsigned long long return_value;
}
int main()
{
Param start_value;
start_value.n = 10; // we will calculate 1+2+...+10
HEAP_FUNCTION<Param> Gauss(&start_value);
// We imagine this is where i define call().
// The code written in this definiton works correctly.
Gauss.call()
{
// Test if the function needs to stop further calls.
if(CURRENT_CALL->PARAM->n == 0)
{
CURRENT_CALL->PARAM->return_value = 0;
return;
}
// Prepare the parameters for the next function call.
CURRENT_CALL->next_call = new THIS_CALL;
CURRENT_cALL->next_call->PARAM = new PARAM_TYPE;
CURRENT_CALL->next_call->prev_call = CURRENT_CALL;
CURRENT_CALL->next_call->PARAM->n = CURRENT_CALL->PARAM->n - 1;
// Call the next instance of the function.
CURRENT_CALL = CURRENT_CALL->next_call;
call();
CURRENT_CALL = CURRENT_CALL->prev_call;
// Collect the return value of the callee.
CURRENT_CALL->PARAM->return_value = CURRENT_CALL->PARAM->n + CURRENT_CALL->next_call->PARAM->return_value;
// Delete the space used by the callee.
delete CURRENT_CALL->next_call;
}
// This is the actual call of the function.
Gauss.call();
// The return value is found in the start_value struct.
std::cout << start_value.return_value << std::endl;
return 0;
}
IMPORTANT NOTE: Derivering the entire class will result in a single call() definition for funtions like sum(a, b) and dif(a, b) since they will use the same PARAM struct. (Even though they are not recursive, and the probability of someone using this is very small, this method is good in a bigger program when some of your functions will have a lot of parameters and just placing them on the heap will result in more stack space)
Don't think I understood the question properly, but did you consider function overloading?

Emulating std::bind in C

I'm using std::bind to provide a callback while abstracting some logic by binding some parameters first. i.e.
void start() {
int secret_id = 43534;
//Bind the secret_id to the callback function object
std::function<void(std::string)> cb = std::bind(&callback, secret_id, std::placeholders::_1);
do_action(cb);
}
void do_action(std::function<void(std::string)> cb) {
std::string result = "hello world";
//Do some things...
//Call the callback
cb(result);
}
void callback(int secret_id, std::string result) {
//Callback can now do something with the result and secret_id
}
So in the above example, the do_action does not need to know about the secret_id and other functions can reuse it without having a secret_id of their own. This is especially useful when do_action is some kind of asynchronous operation.
My question is, is there a way to bind parameter values to function pointers using only C?
If not by emulating std::bind then is there another way to pass data from first() to callback() without complicating the neutral do_action()?
No. C doesn't allow you to do that directly.
In C the standard way to handle callbacks is using context pointers:
void register_callback(void (*cback)(void *context, int data),
void *context);
this means that you will pass a function that will accept a void * in addition to the normal parameters that the callback should handle (in the above case an integer) and you will also pass a void * that you want to be passed back.
This void * normally points to a struct that will contain all the extra parameters or data you need in the callback and using this approach the library doesn't depend on what this context is. If the callback doesn't need any context you just pass a NULL pointer as context and ignore the first parameter when being called from the library.
Something that is kind of hackish and formally unsafe but it's sometimes done is that if the context is a simple data that fits the size of a void * (e.g. an integer) and if your environment is not going to have problems with it you can trick the library by passing a fake void * that is just an integer and you convert it back to an integer when being called from the library (this saves the caller from allocating the context and managing its lifetime).
On how to how to trick the language to avoid this limitation (still remaining in the land of portable C) I can think some hack:
First we allocate a pool of two-arguments callbacks and context data
void (*cbf[6])(int, int);
int ctx[6];
then we write (or macro-generate) functions that we wish to register and that will call the two-arguments versions.
void call_with_0(int x) { cbf[0](ctx[0], x); }
void call_with_1(int x) { cbf[1](ctx[1], x); }
void call_with_2(int x) { cbf[2](ctx[2], x); }
void call_with_3(int x) { cbf[3](ctx[3], x); }
void call_with_4(int x) { cbf[4](ctx[4], x); }
void call_with_5(int x) { cbf[5](ctx[5], x); }
We also store them in a pool where they're allocated and deallocated:
int first_free_cback = 0;
int next_free_cback[6] = {1, 2, 3, 4, 5, -1};
void (*cbacks[6])(int) = { call_with_0,
call_with_1,
call_with_2,
call_with_3,
call_with_4,
call_with_5 };
Then to bind the first parameter we can do something like
void (*bind(void (*g)(int, int), int v0))(int)
{
if (first_free_cback == -1) return NULL;
int i = first_free_cback;
first_free_cback = next_free_cback[i];
cbf[i] = g; ctx[i] = v0;
return cbacks[i];
}
but bound functions must also be explicitly deallocated
int deallocate_bound_cback(void (*f)(int))
{
for (int i=0; i<6; i++) {
if (f == cbacks[i]) {
next_free_cback[i] = first_free_cback;
first_free_cback = i;
return 1;
}
}
return 0;
}
As 6502 explained, it is not possible to do this in portable C without some kind of context argument being passed to the callback, even if it doesn't name secret_id directly. However, there are libraries such as Bruno Haible's trampoline that enable creation of C functions with additional information (closures) through non-portable means. These libraries do their magic by invoking assembly or compiler extensions, but they are ported to many popular platforms; if they support architectures you care about, they work fine.
Taken from the web, here is an example of code that trampoline enables is this higher-order function that takes parameters a, b, and c (analogous to your secret_id, and returns a function of exactly one parameter x that calculates a*x^2 + b*x + c:
#include <trampoline.h>
static struct quadratic_saved_args {
double a;
double b;
double c;
} *quadratic_saved_args;
static double quadratic_helper(double x) {
double a, b, c;
a = quadratic_saved_args->a;
b = quadratic_saved_args->b;
c = quadratic_saved_args->c;
return a*x*x + b*x + c;
}
double (*quadratic(double a, double b, double c))(double) {
struct quadratic_saved_args *args;
args = malloc(sizeof(*args));
args->a = a;
args->b = b;
args->c = c;
return alloc_trampoline(quadratic_helper, &quadratic_saved_args, args);
}
int main() {
double (*f)(double);
f = quadratic(1, -79, 1601);
printf("%g\n", f(42));
free(trampoline_data(f));
free_trampoline(f);
return 0;
}
The short answer is no.
The only thing you can do is declare another function that has the secret_id built into it. If you're using C99 or newer you can make it an inline function to at least limit the function call overhead, although a newer compiler may do that by itself anyway.
To be frank though, that is all std::bind is doing, as it is returning a templated struct, std::bind simply declares a new functor that has secret_id built into it.
An opaque type and keeping secret in a source should do it:
#include <stdio.h>
// Secret.h
typedef struct TagSecret Secret;
typedef void (*SecretFunction)(Secret*, const char* visible);
void secret_call(Secret*, const char* visible);
// Public.c
void public_action(Secret* secret, const char* visible) {
printf("%s\n", visible);
secret_call(secret, visible);
}
// Secret.c
struct TagSecret {
int id;
};
void secret_call(Secret* secret, const char* visible) {
printf("%i\n", secret->id);
}
void start() {
Secret secret = { 43534 };
public_action(&secret, "Hello World");
}
int main() {
start();
return 0;
}
(The above does not address registering callback functions)

How to pass a function to a 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).