How can I include arguments in a function pointer?
This code creates a function pointer that can add two ints:
int addInt(int n, int m) {
return n+m;
}
int (*functionPtr)(int,int);
functionPtr = addInt;
(*functionPtr)(3,5); // = 8
For instance, I want to make a function pointer where the first argument is always 5, so that the function takes one int and adds five. And another one where the first argument is 8.
Is this possible using addInt? Something like:
// make-believe code that of course won't work
int (*functionPtr)(int);
functionPtr = addInt(5);
(*functionPtr)(3); // = 8
(*functionPtr)(9); // = 14
Use std::bind like this:
using namespace std::placeholders;
auto f = std::bind(addInt, 5, _1);
f(1); //returns 6
Use std::bind and placeholders
#include <iostream>
#include <functional>
using namespace std;
int addInt(int n, int m) {
return n+m;
}
int main() {
int (*functionPtr)(int,int);
functionPtr = addInt;
(*functionPtr)(3,5); // = 8
auto f2 = std::bind( addInt, std::placeholders::_1, 5);
auto f3 = std::bind( addInt, 8, std::placeholders::_1);
std::cout << f2(1) << "\n";;
std::cout << f3(1) << "\n";;
}
Output:
6
9
What you really want is a closure (you might also want curryfication, but C++ don't have that; consider switching to Ocaml if you really want it).
C+14 and C++11 have closures (but not earlier versions of C++). Read about C++ lambda functions (or anonymous functions) and the standard <functional> header and its std::function template.
Here is the function which given some integer d returns the translation by d i.e. the function taking an integer x and returning x+d
#include <functional>
std::function<int(int)> translation(int d) {
return [=](int x) { return addInt(x,d) /* or x+d */ ; };
}
Notice that std::function-s are not just C function pointers. They also contain closed values (d in my translation example)
The auto and decltype specifiers are tremendously useful.
For example:
auto addfive = translation(5);
std::cout << addfive(3) << std::end; // should output 8
Related
Here is simple example of using std::function
#include <iostream>
#include <functional>
//A function that sums two numbers.
//Arguments having default values.
void SumOfTwoNumbers(int a = 42, int b = 42)
{
std::cout << "Sum of two numbers :: " << a + b << std::endl;
}
int main()
{
std::function<void(int, int)> testFunc = SumOfTwoNumbers;
SumOfTwoNumbers(); //Works
testFunc(); //Compile time error
testFunc(40, 40); //Works
return 0;
}
In the main function, there are three function calls. The first one and the last one works. Whereas the second call testFunc() without any arguments gives compile time error.
Shouldn't it consider the default arguments and execute successfully?
No, the default values for function arguments are not part of the function signature. They are evaluated at the call site only.
You could use a lambda but then you'd need to redefine the default values:
auto testFunc = [](int a = 42, int b = 42) { SumOfTwoNumbers(a, b); };
... and storing such a lambda in a std::function would again result in the same problem since the signature of the lambda is also void(int, int).
You could however define your own wrapper functor (instead of using std::function) that has multiple operator() overloads:
struct {
void operator()() { SumOfTwoNumbers(42, 42); }
void operator()(int a) { SumOfTwoNumbers(a, 42); }
void operator()(int a, int b) { SumOfTwoNumbers(a, b); }
} testFunc;
In Python, it is possible to store a function pointer with different number of arguments and store the arguments in a list and then unpack the list and call that function like:
def Func(x1, x2):
return x1+x2
ArgList = [1.2, 3.22]
MyClass.Store(Func)
MyClass.FuncPtr(*ArgList)
Is it possible in c++ to do a similar thing?
For example, store the function with the variable-number of inputs and the values in a std::vector and call function pointer by that vector?
I don’t want to define the argument list as a vector.
Is it possible in c++ to do a similar thing?
If you know the arguments(types) at compile-time, of-course you can!
For, instance like/similar to what #Evg suggested, make the Func as a variadic-generic-lambda, and with the support of c++17's std::apply,(for future readers) you could do.
(See a demo)
#include <iostream>
#include <utility> // std::forward
#include <tuple> // std::apply
constexpr auto func_lambda = [](auto&&... args) {
return (std::forward<decltype(args)>(args) + ...); // fold expression
};
int main()
{
std::cout << std::apply(func_lambda, std::make_tuple(1, 2, 3)); // prints 6!
return 0;
}
And now as per your python demo code, you could pack the above idea into to a class-template.
Here, you can avoid the use of std::function, as the Func will be the lambda you pass, and can be stored as compiler deduced lambda unspecified type.
(See Demo Online)
#include <iostream>
#include <utility> // std::forward
#include <tuple> //std::apply, std::make_tuple
// `Func` as variadic-generic-lambda
constexpr auto func_lambda = [](auto&&... args) noexcept {
return (std::forward<decltype(args)>(args) + ...);
};
template<typename Func>
class MyClass final
{
Func mFunction;
public:
explicit MyClass(Func func) // Store: pass the lambda here!
: mFunction{ func }
{}
template<typename... Args> // to execute the `Func` with `Args`!
constexpr auto execute(Args&&... args) const noexcept
{
return std::apply(mFunction, std::make_tuple(std::forward<Args>(args)...));
}
};
int main()
{
MyClass myClass{ func_lambda }; // MyClass.Store(Func)
std::cout << myClass.execute(1.2, 2.82, 3); // MyClass.FuncPtr(*ArgList)
return 0;
}
Output:
7.02
Unfortunately it is not possible to call an arbitrary function passing arbitrary values in a complete dynamic way at runtime. At least some part of the C++ code must compile a static call to a function with the same exact signature.
The problem is that in C++ the parameter passing can only be handled by the compiler and even variadic functions (e.g. printf) where only inspection is performed at runtime normally require a different and simpler calling convention.
One technical problem is that modern ABIs are extremely complex and asymmetrical (e.g. some parameters in registers, some in special FPU registers, some in the stack) and are only handled at compile time.
What you can do is "wrap" the functions you want to be able to call in a function accepting for example an std::vector of generic values and then calling the function passing those parameters converted to the proper type, e.g. something like
Value myabs(const std::vector<Value>& args) {
if (args.size() != 1) throw std::runtime_error("Bad arity");
return Value(fabs(args[0].to<double>()));
}
then it is easy to dynamically call these wrappers because the signature is the same for all of them.
Those wrappers unfortunately must be written (or generated) for each of the functions you need to be able to call so the compiler can actually generate the code needed to call the regular C++ functions.
I am not a template expert, but C++ metaprogramming can be used to generate the wrappers instead of coding each of them manually or writing an external code generator.
This is a very basic example:
typedef Value (*FWrapper)(const std::vector<Value>&);
template<typename RV, typename T1, typename T2, RV (*f)(T1, T2)>
Value wrapper2(const std::vector<Value>& args) {
if (args.size() != 2) throw std::runtime_error("Bad arity");
return f(args[0].to<T1>(), args[1].to<T2>());
}
For example to wrap double atan2(double, double) you can simply write:
FWrapper myatan2 = &wrapper2<double, double, double, &atan2>;
I tried a bit without success to avoid passing explicitly the return value type and number and types of parameters and to extract them instead from the passed function pointer, but may be that is also possible or even practical with recent C++.
The idea is basically to invoke the compiler to build a specific function call on demand when doing a template instantiation.
Not exactly the same thing but in C++ you can apply a combining function to a range of values to produce a single result. std::accumulate can help you here. However, it works with a given range, not variadic arguments.
#include <numeric>
#include <vector>
#include <functional>
#include <iostream>
class MyClass
{
public:
template<typename F, typename T>
T Execute(F &&fn, const T initialValue, const std::vector<T> &values)
{
auto result = std::accumulate(values.begin(), values.end(),
initialValue, std::forward<F>(fn));
return result;
}
};
int main()
{
MyClass cls;
std::vector<double> values = { 1.2, 3.22 };
auto sum = cls.Execute(std::plus<double>{}, 0.0, values);
std::cout << "Sum = " << sum << std::endl;
auto product = cls.Execute(std::multiplies<double>{}, 1.0, values);
std::cout << "Product = " << product << std::endl;
std::vector<int> values2 = { 10, 20 };
auto subtractFrom200 = cls.Execute(std::minus<int>{}, 200, values2);
std::cout << "Subtract from 200 = " << subtractFrom200 << std::endl;
std::vector<std::string> mystrings = {"Hello", " ", " world", ". ", "Bye!"};
auto concatenate = cls.Execute([](std::string a, std::string b){ return a + b ;}, std::string(), mystrings);
std::cout << "Concatenation = " << concatenate << std::endl;
std::vector<double> values3 = {100, 98, 3.5, 50};
auto findMin = [](double a, double b){ return std::min(a, b); };
auto lowest = cls.Execute(findMin, values3.front(), values3);
std::cout << "Min = " << lowest << std::endl;
}
Demo
Note: the fourth parameter to std::accumulate is optional and if omitted it will return the sum of the values. However, you can provide your own binary function if you want to do something else, e.g. multiplication or subtraction.
I want to be able to store a pointer of a function in a struct or class, then I can call upon that function when a button is pressed? here is what I have:
struct INFO
{
std::function<int(int, int)> call_back;
};
class YO
{
public:
YO() {};
~YO() {};
int SUM(int A, int B) { return A + B; }
};
int main()
{
//std::function<int(int, int)> datFunc = SUM;
INFO info;
YO* yo = new YO();
info.call_back = yo->SUM;
//std::function<int(int, int)> func =;
std::cout << info.call_back(10, 10) << std::endl;
system("pause");
return 0;
}
I get errors:
Error C3867 'YO::SUM': non-standard syntax; use '&' to create a pointer to member FunctionPointertest
Error C2679 binary '=': no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion) FunctionPointertest
You need to also supply an instance of the host object to the function call, in this case of class YO. std::function supports this, amongst many conversions it can do, but then the prototype becomes
std::function<int(YO*, int, int)> call_back;
And when you call it:
info.call_back(&yo, 10, 10)
Some options to do what you want. Using the lambda is the best solution.
void func() {
INFO info;
YO yo;
YO* yo2 = new YO;
info.call_back = [&yo](int a, int b) {
return yo.SUM(a, b);
};
using namespace std::placeholders;
info.call_back = std::bind(&YO::SUM, std::ref(yo), _1, _2);
info.call_back = std::bind(&YO::SUM, yo2, _1, _2);
}
P.S. You don't usually want to use new in c++.
Here are a set of Variadic Template Classes that will enable you to do this with ease if you have C++17 available to you. The first class simply stores a generic version of a std::function of any type! The second class stores the first class through a member function and will register either a function pointer, a function object or a lambda. It also has another member function that will invoke it. I am currently using lambdas in this example. I have two lambdas, the 1st takes two int types adds them and returns an int as in your problem above. The 2nd takes two std::strings concatenates them then prints them to the screen but does not return any value. You can even expand this by having a std::vector<Functor<>> stored in the driver class. The register_callback would change slightly as to pushing them into the vector, and the call_back you have options. You could either call them all in one go, or search via an index value to call a specific one, but I'll leave that as an exercise to you.
#include <string>
#include <iostream>
#include <functional>
template<typename RES_TYPE, typename... ARG_TYPES>
struct Functor {
std::function<RES_TYPE( ARG_TYPES... )> func_;
};
template<typename RES_TYPE, typename... ARG_TYPES>
class Driver {
private:
Functor<RES_TYPE, ARG_TYPES...> functor;
public:
Driver() = default;
~Driver() = default;
void register_callback( const Functor<RES_TYPE, ARG_TYPES...> &func ) {
functor = func;
}
RES_TYPE call_back( ARG_TYPES... args ) {
return functor.func_( std::forward<ARG_TYPES>(args)... );
}
};
int main() {
// Function Type: int ( int, int );
Functor<int, int, int> func;
auto lambda = []( int a, int b ) { return a + b; };
func.func_ = lambda;
Driver<int, int, int> driver;
driver.register_callback( func );
int a = 3;
int b = 5;
std::cout << driver.call_back( a, b ) << '\n';
std::cout << driver.call_back( 7, 5 ) << '\n';
// Function Type: void ( string, string );
Functor<void, std::string, std::string> func2;
auto lambda2 = []( std::string str1, std::string str2 ) {
str1 = str1 + " " + str2;
std::cout << str1 << '\n';
};
Driver <void, std::string, std::string> driver2;
func2.func_ = lambda2;
driver2.register_callback( func2 );
std::string str1 = "Hello";
std::string str2 = "World";
driver2.call_back( str1, str2 );
driver2.call_back( "Generic", "Programming" );
return 0;
}
The output is:
8
12
Hello World
Generic Programming
If you notice with this code here; there is no need to mess with pointers or dynamic memory. This is all taken care of by the use of std::function for us and the default dtors of the classes.
I tried my best to design this with simplicity, readability while making it portable and generic as possible. I am sure there can be some improvements made, but I think this is in line of what you are asking for.
I have some questions regarding this program:
#include <iostream>
#include <type_traits>
#include <functional>
using namespace std;
template <typename T> void foo ( T x )
{
auto r=ref(x);
cout<<boolalpha;
cout<<is_same<T&,decltype(r)>::value;
}
int main()
{
int x=5;
foo (x);
return 0;
}
The output is:
false
I want to know, if std::ref doesn't return the reference of an object, then what does it do? Basically, what is the difference between:
T x;
auto r = ref(x);
and
T x;
T &y = x;
Also, I want to know why does this difference exist? Why do we need std::ref or std::reference_wrapper when we have references (i.e. T&)?
Well ref constructs an object of the appropriate reference_wrapper type to hold a reference to an object. Which means when you apply:
auto r = ref(x);
This returns a reference_wrapper and not a direct reference to x (ie T&). This reference_wrapper (ie r) instead holds T&.
A reference_wrapper is very useful when you want to emulate a reference of an object which can be copied (it is both copy-constructible and copy-assignable).
In C++, once you create a reference (say y) to an object (say x), then y and x share the same base address. Furthermore, y cannot refer to any other object. Also you cannot create an array of references ie code like this will throw an error:
#include <iostream>
using namespace std;
int main()
{
int x=5, y=7, z=8;
int& arr[] {x,y,z}; // error: declaration of 'arr' as array of references
return 0;
}
However this is legal:
#include <iostream>
#include <functional> // for reference_wrapper
using namespace std;
int main()
{
int x=5, y=7, z=8;
reference_wrapper<int> arr[] {x,y,z};
for (auto a: arr)
cout << a << " ";
return 0;
}
/* OUTPUT:
5 7 8
*/
Talking about your problem with cout << is_same<T&,decltype(r)>::value;, the solution is:
cout << is_same<T&,decltype(r.get())>::value; // will yield true
Let me show you a program:
#include <iostream>
#include <type_traits>
#include <functional>
using namespace std;
int main()
{
cout << boolalpha;
int x=5, y=7;
reference_wrapper<int> r=x; // or auto r = ref(x);
cout << is_same<int&, decltype(r.get())>::value << "\n";
cout << (&x==&r.get()) << "\n";
r=y;
cout << (&y==&r.get()) << "\n";
r.get()=70;
cout << y;
return 0;
}
/* Ouput:
true
true
true
70
*/
See here we get to know three things:
A reference_wrapper object (here r) can be used to create an array of references which was not possible with T&.
r actually acts like a real reference (see how r.get()=70 changed the value of y).
r is not same as T& but r.get() is. This means that r holds T& ie as its name suggests is a wrapper around a reference T&.
I hope this answer is more than enough to explain your doubts.
std::reference_wrapper is recognized by standard facilities to be able to pass objects by reference in pass-by-value contexts.
For example, std::bind can take in the std::ref() to something, transmit it by value, and unpacks it back into a reference later on.
void print(int i) {
std::cout << i << '\n';
}
int main() {
int i = 10;
auto f1 = std::bind(print, i);
auto f2 = std::bind(print, std::ref(i));
i = 20;
f1();
f2();
}
This snippet outputs :
10
20
The value of i has been stored (taken by value) into f1 at the point it was initialized, but f2 has kept an std::reference_wrapper by value, and thus behaves like it took in an int&.
A reference (T& or T&&) is a special element in C++ language. It allows to manipulate an object by reference and has special use cases in the language. For example, you cannot create a standard container to hold references: vector<T&> is ill formed and generates a compilation error.
A std::reference_wrapper on the other hand is a C++ object able to hold a reference. As such, you can use it in standard containers.
std::ref is a standard function that returns a std::reference_wrapper on its argument. In the same idea, std::cref returns std::reference_wrapper to a const reference.
One interesting property of a std::reference_wrapper, is that it has an operator T& () const noexcept;. That means that even if it is a true object, it can be automatically converted to the reference that it is holding. So:
as it is a copy assignable object, it can be used in containers or in other cases where references are not allowed
thanks to its operator T& () const noexcept;, it can be used anywhere you could use a reference, because it will be automatically converted to it.
Added an example to show the difference in value you get when you pass the T& and ref(T) arguments in the bind function.
std::bind copies the argument provided unless it is passed by std::ref()/std::cref().
void f(int r1, int& r2, int w1, int& w2)
{
std::cout << r1 << r2 << w1 << w2; // 5 5 10 10
r1 = 9, r2 = 9, w1 = 9, w2 = 9;
}
int main()
{
int w1 = 5, w2 = 5, n1 = 5, n2 = 5;
int& r1 = n1;
int& r2 = n2;
std::function<void()> bound_f = std::bind(f, r1, r2, std::ref(w1), std::ref(w2));
r1 = 10, r2 = 10, w1 = 10, w2 = 10;
bound_f(); // 5 5 10 10
std::cout << r1 << r2 << w1 << w2; // 10 10 10 9
}
I have searched the reference and a general web, but I am unable to find out, if it exists.
Is there a way to get a pointer to the current function in C++? It is so trivial, that it should exist.
In the perfect world I would want to find a way to get an std::function of current function, but even an old style pointer would do.
To clarify why it may be needed: I am thinking about recursion inside a Lambda function or even general recursion in a function, with the high potential of the name change in the future releases.
There isn't, largely because there's no need for it. In the context of a (non-anonymous function) function, you always know where you stand - you can always use its name to refer to it or get its address. Unlike objects, where different ones have different addresses, ergo the need for this.
In general you can't. For example, in a lambda that's convertible to raw function pointer, there's no (standard language) way to obtain that pointer inside the function.
However, you can obtain the function name as a raw string, via the macro __func__, except that only the newest versions of the compilers provide it with that macro name.
Also, if you are OK with non-portable code there are several compiler-specific introspection facilities (I just know they exist, but would have to google them for you to list them).
Addressing the question's newly added part, how to let a function be recursive and still support easy name change and/or lambdas.
One way is to use a std::function, but much easier (and possibly a bit more efficient) is to just define the recursive function as an internal implementation detail, e.g. in a namespace or in an inner class:
#include <iostream>
using namespace std;
void foo( int const x )
{
struct Recursive {
inline static void foo( int const x )
{
cout << x << ' ';
if( x > 0 ) { foo( x - 1 ); }
}
};
Recursive::foo( x );
cout << endl;
}
auto main() -> int
{
foo( 3 );
}
How to do the above with a lambda instead of a named function:
#include <iostream>
using namespace std;
auto main() -> int
{
auto const foo = []( int const x ) -> void
{
struct Recursive {
inline static void foo( int const x )
{
cout << x << ' ';
if( x > 0 ) { foo( x - 1 ); }
}
};
Recursive::foo( x );
cout << endl;
};
foo( 3 );
}
If the purpose is just to obtain a std::function object, you might use the function name itself:
#include <iostream>
#include <functional>
using namespace std;
void functionA(int a);
void functionA(int a)
{
cout << "Thanks for calling me with " << a << endl;
if(a == 22)
return;
std::function<void(int)> f_display = functionA;
f_display(22);
}
int main() {
functionA(1);
return 0;
}
http://ideone.com/4C9gc5
but this isn't immune to name changing unfortunately. You might also encapsulate the function into something else to get rid of name changing:
#include <iostream>
#include <functional>
using namespace std;
void functionA(int a)
{
cout << "Thanks for calling me with " << a << endl;
}
template <typename F>
void encapsulateFunction(F f, int val)
{
std::function<void(int)> f_display = f;
// f_display now points to the function encapsulated
f_display(val);
}
int main() {
encapsulateFunction(functionA, 22);
return 0;
}
http://ideone.com/5Xb0ML
you can do this:
std::map<string, boost::any> functions;
int foo(int x) {
int (*fp)(int) = boost::any_cast<int (*)(int)>(functions[__func__]);
return x;
}
int main(int argc, char* argv[])
{
int (*fooPointer)(int) = foo;
boost::any fp = fooPointer;
functions["foo"] = fp;
...
}
insert a reference to the function into a global map and retrieve it from within the function. There's still room for encapsulating the map but I hope the idea is clear.
In c++ function is not a first class citizen so you will have to work a bit to get the function's reference.