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.
Related
I was reading about std::invoke on cpp reference and was wondering in which situations we would ever need to pass as a first argument a pointer to data member and an object as second argument.
From cpp reference it states this:
Invoke the Callable object f with the parameters args. As by INVOKE(std::forward(f), std::forward(args)...).
where INVOKE(f, t1, t2, ..., tN) is defined as follows:
...
and then the second point is:
Otherwise, if N == 1 and f is a pointer to data member of class
Ok, let's look at this further and suppose I'm using std::thread (which constructor's uses std::invoke):
For example, it is a bit unclear to me when it would be useful (or what can force one) to use a threads this way ?
struct Foo {
Foo(int num) : num_(num) {}
void print_add(int i) const { std::cout << num_+i << '\n'; }
int num_;
void print_num(int i) const {
std::cout << i << '\n';
}
};
int main() {
const Foo foo(314159);
std::thread t(&Foo::num_, foo);
t.join();
return 0;
}
And how a pointer to data member can be associated with a callable concept ?
You might think that only pointers to member functions are useful. That is, something like:
struct Widget {
bool valid() const;
};
std::vector<Widget> widgets;
bool all_valid = std::ranges::all_of(widgets, &Widget::valid);
That would std::invoke the pointer to member function &Widget::valid on each of the Widgets. But you could just as easily have constructed Widget such that valid is just a flag instead of being a member function. And checking that all the Widgets are valid is just as reasonable a thing to do:
struct Widget {
bool valid;
};
std::vector<Widget> widgets;
bool all_valid = std::ranges::all_of(widgets, &Widget::valid);
The only difference is that this std::invokes a pointer to member data instead of a pointer to member function. But still useful.
#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 have two classes with the following structure:
struct A {
A transform() const;
};
struct B {
// returns a temporary A
A operator*() const;
};
The * operator may look a little weird here, but given the context of its usage is actually pretty natural. In fact, B really exists only to provide some syntatic sugar for an embedded language, so it's methods and operators are designed to give desired look to code. Given B b, getting the associated A is fast, *b. I sometimes want to call the transform on A immediately. Currently, this requires some extra parentheses (*b).transform(). There seems like a natural simplification, namely b->transform(). But operator -> is supposed to return a pointer and operator * is returns a temporary. How can I implement an overload like that?
Disclaimer: I'm not responsible for any confusions that arise from changing the value category of the overloaded operators from their built-in counterparts.
struct just_some_type
{
int m;
int transform() { return m; }
};
// the intermediate helper stops the recurring application of ->
// if the lhs of -> is of a class type
struct intermediate_helper
{
just_some_type member;
just_some_type* operator->() { return &member; }
};
struct ptr_like
{
just_some_type operator*()
{ return {42}; }
intermediate_helper operator->()
{ return {{42}}; }
};
Usage example:
#include <iostream>
int main()
{
auto p = ptr_like{};
std::cout << (*p).transform() << "\n";
std::cout << p->transform() << "\n";
}
Important note: the object acted upon in p-> is an lvalue, as the built-in -> is applied to a pointer! E.g. if you qualify transform with an lvalue-ref like int transform() &;, then the version (*p).transform() will fail to compile, but p->transform() still is legal.
This question already has answers here:
Why do we use std::function in C++ rather than the original C function pointer? [duplicate]
(3 answers)
Closed 9 years ago.
The notation for std::function is quite nice when compared to function pointers. However, other than that, I can't find a use case where it couldn't be replaced by pointers. So is it just syntactic sugar for function pointers?
std::function<> gives you the possibility of encapsulating any type of callable object, which is something function pointers cannot do (although it is true that non-capturing lambdas can be converted to function pointers).
To give you an idea of the kind of flexibility it allows you to achieve:
#include <functional>
#include <iostream>
#include <vector>
// A functor... (could even have state!)
struct X
{
void operator () () { std::cout << "Functor!" << std::endl; }
};
// A regular function...
void bar()
{
std::cout << "Function" << std::endl;
}
// A regular function with one argument that will be bound...
void foo(int x)
{
std::cout << "Bound Function " << x << "!" << std::endl;
}
int main()
{
// Heterogenous collection of callable objects
std::vector<std::function<void()>> functions;
// Fill in the container...
functions.push_back(X());
functions.push_back(bar);
functions.push_back(std::bind(foo, 42));
// And a add a lambda defined in-place as well...
functions.push_back([] () { std::cout << "Lambda!" << std::endl; });
// Now call them all!
for (auto& f : functions)
{
f(); // Same interface for all kinds of callable object...
}
}
As usual, see a live example here. Among other things, this allows you to realize the Command Pattern.
std::function is designed to represent any kind of callable object. There are plenty of callable objects that cannot be represented in any way by a function pointer.
A functor:
struct foo {
bool operator()(int x) { return x > 5; }
};
bool (*f1)(int) = foo(); // Error
std::function<bool(int)> f2 = foo(); // Okay
You cannot create an instance of foo and store it in a bool(*)(int) function pointer.
A lambda with a lambda-capture:
bool (*f1)(int) = [&](int x) { return x > y; }; // Error
std::function<bool(int)> f2 = [&](int x) { return x > y; }; // Okay
However, a lambda without a capture can be converted to a function pointer:
The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.
Implementation-defined callable return values:
bool foo(int x, int y) { return x > y; };
bool (*f1)(int) = std::bind(&foo, std::placeholders::_1, 5); // Error (probably)
std::function<bool(int)> f2 = std::bind(&foo, std::placeholders::_1, 5); // Okay
std::bind's return value is an implementation-defined callable object. Only how that object may be used is specified by the standard, not its type.