I am using bind() to bind a function and its parameters together. I used the build-in functor multiplies and I also tried a function I wrote myself AddVal2(). The following is a correct version of the code. But I really don't understand why std::bind(std::multiplies<int>(),std::placeholders::_1,10) has to include () with multiplies<int>, while bind(AddVal2,std::placeholders::_1,10) write AddVal2 instead of AddVal2(). Thank you.
#include<iostream>
#include<vector>
#include<algorithm>
void AddVal2(int x, int y)
{ std::cout << x+y << std::endl;}
int main()
{
std::vector<int> vec = {1,2,3,4,5};
std::vector<int> vec_result;
std::transform(vec.begin(),vec.begin()+2,std::back_inserter(vec_result),std::bind(std::multiplies<int>(),std::placeholders::_1,10));
for (std::vector<int>::iterator itr = vec_result.begin(); itr !=vec_result.end();++itr){std::cout << *itr << std::endl;}
for_each(vec.begin(),vec.end(),std::bind(AddVal2,std::placeholders::_1,10));
}
That's simple: std::multiplies<T> is a class template which defines a
function call operator. It looks something like this:
template <typename T>
struct multiplies {
// some typedefs are here, too
T operator()(T const& a0, T const& a1) const { return a0 * a1; }
};
To create such an object, you'll use a default constructor, i.e., std::multiplies<T>().
On the other hand AddVal2 is a function. To get a function object from a normal function you just mention the function and it'll decay into a function pointer. Alternatively you can also use &AddVal2 to explicitly obtain a function pointer (for member functions you have to explicitly take the address).
Related
#include <iostream>
template <int N>
class X {
public:
using I = int;
void f(I i) {
std::cout << "i: " << i << std::endl;
}
};
template <int N>
void fppm(void (X<N>::*p)(typename X<N>::I)) {
p(0);
}
int main() {
fppm(&X<33>::f);
return 0;
}
I just don't understand the compile error message of the code.
error: called object type 'void (X<33>::*)(typename X<33>::I)' is not a function or function pointer
p(0);
I think p is a function which returns void and takes int as its argument. But apparently, it's not. Could somebody give me clue?
Since p is a pointer to a nonstatic member function, you need an instance to call it with. Thus, first instantiate an object of X<33> in main:
int main() {
X<33> x;
fppm(x, &X<33>::f); // <-- Signature changed below to accept an instance
Then in your function, change the code to accept an instance of X<N> and call the member function for it:
template <int N>
void fppm(X<N> instance, void (X<N>::*p)(typename X<N>::I)) {
(instance.*p)(0);
}
The syntax may look ugly but the low precedence of the pointer to member operator requires the need for the parentheses.
As denoted in the comments already, p is a pointer to member function, but you call it like a static function (p(0);). You need a concrete object to call p on:
X<N> x;
(x.*p)(0);
// or:
X<N>* xx = new X<N>();
(xx->*p)(0);
delete xx;
Be aware that the .*/->* operators have lower precedence than the function call operator, thus you need the parentheses.
Side note: Above is for better illustration, modern C++ might use auto keyword and smart pointers instead, which could look like this:
auto x = std::make_unique<X<N>>();
(x.get()->*p)(0);
I am trying to write a general integral function and I would like to implement it in such a way so that it can accept any mathematical function. That is, I would like to pass the math function as an input parameter. In pseudo-code: simpson_int(x*x). I've heard of the function template in <functional> but I don't really have experience with templates in C++.
There are some solutions that comes in my mind (and this is my approach at the problem, for sure there are more solution, and maybe what I'm pointing out is not the best), that consider the fact that you need to call the argument function more than once in the Simpson implementation (thus you need a "callable" argument):
Function pointer
Function pointers (more C than C++), where you declare with two arguments: the first one will be the pointer to a function with the specified types, while the second is the argument for your function. Lets
make an example:
#include <iostream>
double power2(double x) {
return x * x;
}
double simspon(double (*f)(double), double x) {
return f(x);
}
int main() {
std::cout << simspon(power2, 2);
return 0;
}
In this case I have used no templates for reaching the result. But this will not take any function as first argument, but only a function that has as argument a double and returns a double.
I think that most of c++ programmer will suggest you to avoid this method.
Function pointer and templates
So you maybe want to expand the previous example using templates and making it more general. It is quite simple to redefine the function
to accept a template (an abstract type) that you actually specify only when you use it in your code:
#include <iostream>
double power2(double x) {
return x * x;
}
int power2int(int x) {
return x * x;
}
template <class T, class P>
P simspon(T (*f)(P), P x) {
return f(x);
}
int main() {
std::cout << simspon<double, double>(power2, 2.0);
std::cout << simspon<int, int>(power2int, 2);
return 0;
}
T and P are two templates: the first one is used for describing the returned value of the function pointer, while the second specify the argument of the function pointer, and the returned value of simpson.So when you are writing template <class T, classP> you are actually informing the compiler that that you are using T and P as placeholder for different type. You will actually declare the type that you want later on, when you will call the function in the main. This is not good code but I'm building the path to understand templates. Also, you specify the type of your argument function when you actually call simpson, with the < >.
(Disclaimer: you should consider to use template <typename T ...> instead of class. But I'm used with the old class and there are situation in which typename cannot be used, there are a lot of questions on SO that dive into this.)
Using std::function
Instead of using a function pointer as argument you may want to create a variable that stores your function to be passed as argument of simpson. This bring several advantages, because they are actually an object inside your code that have some predictable behavior in some unwanted circumstances (for example, in case of a null function pointer you have to check the pointer itself and handle it, in case of std::function if there is no callable pointer it throws std::bad_function_call error)
Here an example, and it uses again templates, as before:
#include <iostream>
#include <functional>
double power2(double x) {
return x * x;
}
int power2int(int x) {
return x * x;
}
template <class T, class P>
P simspon(std::function<T(P)> f, P x) {
return f(x);
}
int main() {
std::function<double(double)> p_power2 = power2;
std::cout << simspon<double, double>(p_power2, 2.0);
std::function<double(double)> p_power2int = power2int;
std::cout << simspon<int, int>(power2int, 2);
return 0;
}
Using lambdas
lambdas are closure and in your case (if you can use the standard C++14) can be used alongside the auto keyword to achieve quite a general behavior, without the explicit use of templates. The closure are also able to capture part/the whole context, check the reference for this.
Let's see an example, in which I create two lambdas that receive different arguments and a simpson function that is quite general (actually it is not, is the compiler that defines different functions with respect to the call that you do).
#include <iostream>
auto lambda = [](auto x) { return x * x ; };
auto lambda_2 = [] (int x) { return x + 10; };
auto simpson(auto f, auto x) {
return f(x);
}
int main() {
std::cout << simpson(lambda, 2.0);
std::cout << simpson(lambda_2, 1);
return 0;
}
You need to compile it with the -std=c++14 flag. There are tons of advise that comes in my mind to suggest you to avoid to implement your code in this way, remember that it has only some illustrative purposes (I've more than exaggerated with the auto keyword).
Function objects (the Problem class)
Maybe an improvement for your case is to write a general class for the mathematical functions to integrate and pass the object to your function. This bring several advantages: you may want to save some of the integrative result inside your function or even write the stream operator to pretty print your problem. This is the solution employed typically by mathematical libraries.
In this extremely simple case, we have a class that is a problem. When you create a new instance for this class, a std::function is passed to the constructor and stored inside the class. The instance of the class is the argument for your simpson:
#include <iostream>
#include <functional>
template <class T, class P>
class Problem {
public:
// Attributes
std::function<T(P)> _f;
// Constructor
Problem(std::function<T(P)> f) : _f(f) {};
// Making the object callable
P operator()(P x) { return _f(x); }
};
template <class T, class P>
P simspon(Problem<T, P> p, P x) {
return p(x);
}
int main() {
Problem<double, double> prb([](double x) { return x * x; });
std::cout << simspon<double, double>(prb, 2);
return 0;
}
Use std::function, like this for example:
#include <iostream> // std::cout
#include <functional> // std::function
int main()
{
std::function<double(double)> simpson_int =([](double x) { return x * x; };
std::cout << "simpson_int(4): " << simpson_int(4) << '\n';
return 0;
}
which outputs:
simpson_int(4): 16
I was going through following code:
template <typename String>
void test_decimals()
{
SensibleLessThan<String> mycomparison;
String lhs = "1.212";
String rhs = "1.234";
CHECK_EQUAL(mycomparison(lhs, rhs), true); // CHECK EQUAL is macro
}
I do not understand the meaning of the following constructs:
SensibleLessThan<String> mycomparison;
mycomparison(lhs, rhs)
Is mycomparison an object, a function or a function pointer?
SensibleLessThan<String> is a type. mycomparison is an object of that type. Now it appears that the type overloads operator(), which allows it to be called as though it were a function. Objects of such types are usually known as function objects or functors. Such objects are, like functions, considered callable.
For a simple example, here's an adder struct that overloads operator(). We can create an object of the adder type and then use that object as though it were a function.
#include <iostream>
struct adder
{
int operator()(int a, int b) { return a + b; }
};
int main()
{
adder my_adder;
std::cout << my_adder(5, 6) << std::endl;
}
Here it is in action. In fact, a similar type already exists in the C++ standard library: std::plus.
Is it possible to create an std::vector that can hold an std::function with any signature?
(The function arguments would all be pre-bound.)
I tried std::vector<std::function<void()> >, since if I only have one std::function of that type I can bind any function to it.
This does not seem to work inside a vector: if I try to add a function with std::bind to the vector that has a signature other than void(), I get:
No matching member function for call to 'push_back'
Is there a way to do this?
Edit:
I just remembered that std::function<void()> does allow you to bind any function that returns void as long as the arguments are pre-bound with std::bind, it does not allow you to bind any signature though, but for my purposes it's generic enough, so the following works:
class A
{
public:
void test(int _a){ return 0; };
};
A a;
std::vector<std::function<void()> > funcArray;
funcArray.push_back(std::bind(&A::test, std::ref(a), 0));
This should work:
#include <iostream>
#include <functional>
#include <vector>
void hello() { std::cout << "Hello\n"; }
void hello2(const char * name) { std::cout << "Hello " << name << '\n'; }
int main()
{
std::vector<std::function<void()>> v;
v.push_back(hello);
v.push_back(std::bind(hello2, "tim"));
v[0]();
v[1]();
}
How are you doing it?
Is it possible to create an std::vector that can hold an std::function with any signature? (The function arguments would all be pre-bound.)
So you're wondering if you can use a vector to hold objects of different types except that you've wrapped them all up in a single type?
Yes, you can store a bunch of items that all have the same type in a vector.
Or maybe you're trying to ask "How do I wrap callable objects such that they'll have the type I need?"
bind can handle the special case where you only need to remove or reorder parameters in order to get something convertible to the common type. In order to handle the general case where you may need choose the return type, add parameters, etc., you simply have to write new functions. Lambda's can make it easy to do that inline:
std::vector<std::function<common_signature> F;
double foo(std::string);
// for a common signature of void()
F.push_back([]{ foo("hello"); });
int bar(void);
// for a common signature of int (int)
F.push_back( [](int i) { return bar() + i; });
int baz(void);
// for a common signature of std::complex<double> (void)
F.push_back( []() -> std::complex<double> { return {0,baz()}; });
I'm told to create template of function , that will take 4 arguments :
pointer
reference
pointer to array
pointer to function
How to perform this task ? I was trying :
#include <iostream>
using namespace std;
int nothing(int a)
{
return a;
}
template<typename T> T func(int *L, int &M, char *K, int (*P)(int))
{
cout << L << "," << M << "," << K[0] << "," << P() << endl;
return 0;
}
int main()
{
int x = 3;
int *z = &x;
int &y = x;
char c[3];
int (*pf)(int) = nothing;
cout << "some result of func" << func(z, y, c, pf) << endl;
system("pause");
return 0;
}
This gives me "no matching function , I guess for 'pf'. Also now I have no control over what to pass within pf or am I wrong ?
You're almost there. However, in C++, a reference is denoted with & (not $), a pointer to an array is a pointer to its first element, and a function pointer needs additional parentheses: T (*pf)().
Note that it is called a function template (as opposed to class templates).
Edit: (You shouldn't edit your question so that answers given so far suddenly become nonsensical.)
pf(x) calls the function stored in pf. pf already is a function pointer, so pass it as it is.
(Also, in your declaration P is a function taking an X, while pf takes an int. I suppose this is an editing error?)
Note that, with function pointers, there are 1..N types involved, one result type, and 0..N argument types. "Create a function template that will take a pointer to a function" can mean any of that. Or it means
template< typename F >
void f(F func);
which can be called with any function pointer.
To help you little bit more, try to remember how the "main" function taking arguments looks like, this will help you to see how you can make a pointer to an array.
You now have some problems left...
TYPE (*P)(x) says you expect a pointer to function that takes an argument of type x - change it to an existing type.
In the expression func(z, y, c, pf(x)) you try to call the function pointer pf instead of just passing it.
Then you are calling func with parameters based on different types for the first 3 parameters, int and char, but func expects them to be based on the same type.
Try writing down with what types func will be called with and try matching that to a signature for func with TYPE being substituted to say int.
E.g. if you have the following:
template<typename T> void f(T* a, T* b);
and try to call it like this:
int* a = 0;
int* b = 0;
f(a, b);
the compiler instantiates and calls a function
void f<int>(int*, int*);
But if you do the following:
int* a = 0;
char* b = 0;
f(a, b);
what should be called?
void f<int> (int*, int* ); // doesn't match, 2nd argument is char*
void f<char>(char*, char*); // doesn't match, 1st argument is int*