Understanding bind_front when used with classes - c++

[New to CPP bind] I understand bind_front when it is used on context of non class functions. Can someone help me understand the following piece of code, which uses bind_front in context of class ?
#include <iostream>
#include <functional>
class foo
{
void bar() { std::cout << "foo::bar" << '\n'; }
};
int main()
{
Foo my_foo;
auto f1 = std::bind_front(&foo::bar, &my_foo);
f1();
}
Essentially whats binding a function to a class pointer does ?

As documented, calling the function-call operator of the object returned bystd::bind_front function is equivalent to calling std::invoke.
And std::invoke is specified to take the first function argument (i.e. &my_foo in your example) and use as the object to call the member function on.
So your call
f1();
is equivalent to
std::invoke(&foo::bar, &my_foo);
which is equivalent to
(&my_foo)->bar();

Related

How to pass a function as parameter of another function in C++?

I'm trying to build a class made up by a vector of threads.
The class should have a method that take as argument another function, this function has to be executed by a new threads.
I would like to avoid use of native pointer, so I'm not excatly sure how to build this specific method.
You can pass a function like this:
template <typename F>
void call_function(F f) {
f();
}
For example:
#include <iostream>
void sayHello() {
std::cout << "Hello\n";
}
int main() {
call_function(sayHello);
}
regarding your constraints I suggest to use std::function. You can then use std::bind and if using C++20, std::bind_front.
cheers,
FM.

function pointer to overloaded static member - to use as custom deleter in unique_ptr

I have a class with static and overloaded member function.
I want to use one them as a custom deleter in a unique_ptr
there are lots of questions on this topic, none of them worked for me.
#include <iostream>
#include <memory>
#include <functional>
class A {
public:
static void release() {
std::cout << "void released\n";
}
static void release(int*i) {
std::cout << *i << " released\n";
}
};
int main()
{
int i = 10;
std::unique_ptr<int, decltype(&A::release(int*))> ptr(&i, &A::release); // compiler error
std::unique_ptr<int, std::function<void(int*)>> ptr(&i, &A::release); // compiler error
return 0;
}
try it out here: https://onlinegdb.com/H14txk3sL
std::unique_ptr<int, void(*)(int*)> ptr(&i, &A::release);
// ~~~~~~~~~~~~^
This way, std::unique_ptr's constructor will expect a specific type of a pointer, which will help the compiler resolve ambiguity.
This:
decltype(&A::release(int*))
is not a valid syntax. In order yo use decltype(e), you'd have to write decltype(&A::release), but this again would raise an ambiguity error, and so it would have to become:
decltype(static_cast<void(*)(int*)>(&A::release))
but that's a long-winded way of saying void(*)(int*).
This:
std::function<void(int*)>
doesn't help in resolving ambiguity, becuase std::functions's constructor is a template as well, which means the compiler again misses a context that would help it to choose one of the overloaded functions.

function pointers using functions in an object with parameters

I have been playing around with function pointers in c++ and seem to have found a bit of a problem. I made a demo to reproduce the error in a simple example.
I have the header file
class MyClass
{
public:
void MyFunction(int i);
MyClass();
~MyClass();
};
and the cpp file
#include "MyClass.h"
#include <iostream>
#include <functional>
using namespace std;
MyClass::MyClass()
{
//doesn't work
function<void(int)> func = &MyClass::MyFunction;
}
void MyClass::MyFunction(int i)
{
cout << i << endl;
}
In the constructor of the cpp file I am trying to create a pointer to MyFunction. It gives the error error C2664: 'void std::_Func_class<_Ret,int>::_Set(std::_Func_base<_Ret,int> *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base<_Ret,int> *' in the functional file at line 506. It works fine with a parameterless method, but not with them. Does anyone know why, and how to resolve it?
You can use this and bind the object being constructed to the function. For instance, if your constructor looked like this:
MyClass::MyClass()
{
function<void(int)> func = bind(&MyClass::MyFunction, this, placeholders::_1);
func(6);
}
And you created a MyClass instance:
MyClass instance;
Then 6 will be printed to stdout.
You can also use std::mem_fn in C++11, which wraps a member function/variable into a callable closure
#include <iostream>
#include <functional>
class MyClass
{
public:
MyClass()
{
auto func = std::mem_fn(&MyClass::MyFunction);
func(this, 42); // call it on the current instance
}
void MyFunction(int i)
{
std::cout << i << std::endl;
}
};
int main()
{
MyClass foo;
}
or, you can explicitly specify the instance you're calling the pointer to member function
MyClass()
{
auto func = &MyClass::MyFunction;
(this->*func)(42); // call it on the current instance
}
In particular, note that std::function<void(int)> is not convertible to a pointer to member function. See related Using generic std::function objects with member functions in one class
That's why using auto with std::mem_fn gets rid of all the pain.

C++: Constructing std::function from templated method

So, I was trying to get this working:
#include <iostream>
#include <functional>
using namespace std;
class X {
public:
template<typename T>
void f(T t) {
cout << t << endl;
}
};
int main() {
X xx;
xx.f(5);
function<void(int)> ff(&X::f);
return 0;
}
Compiler complains that X::f is <unresolved overloaded function type>, which makes sense. Now, my questions is: how do I tell the compiler which template parameters to use? I essentially want something like
&X::template<int> f
(the equivalent of dot-template for object methods). Any help would be much appreciated.
You would need:
function<void(X, int)> ff(&X::f<int>)
ff(xx, 5);
because you asked for a non-static member function meaning you need to provide the instance on which the function is invoked to std::function. For example: http://ideone.com/dYadxQ
If your member f doesn't actually need an X to operate, you should make it a "free" nonmember function rather than a member function of X.

How do I use a method as an argument for another method?

#include <functional>
#include <iostream>
class Foo{
void print(std::function<void (void)> f){
f();
std::cout << "!";
}
void sayHello(){
std::cout << "Hello";
}
public:
void tell(){
print(sayHello);
}
};
int main(){
auto foo = Foo();
foo.tell(); // 'Foo::sayHello': function call missing argument list; use '&Foo::sayHello' to create a pointer to member
}
I am getting the error C3867: 'Foo::sayHello': function call missing argument list; use '&Foo::sayHello' to create a pointer to member. If I use &Foo::sayHello then I'll get a bunch of templating errors.
What did I do wrong?
sayHello is a non-static member function, so it has an implicit first argument, the this pointer. The simplest way to get your code to work is to use a lambda expression that captures the this pointer.
void tell(){
print([this]{sayHello();});
}
Another option is std::bind
void tell(){
print(std::bind(&Foo::sayHello, this));
}
You want to pass a member function as argument, however a member function must be called on an object instance.
A possible solution is the following:
void tell(){
print(std::bind(&Foo::sayHello, this));
}
A member function has an additional parameter: the this pointer. You are just assuming the declaration of the function has none
void (void)
The bind() function can help you bind that pointer into it and return an object suitable for a std::function wrapper
#include <functional>
#include <iostream>
class Foo{
void print(std::function<void (void)> f){
f();
std::cout << "!";
}
void sayHello(){
std::cout << "Hello";
}
public:
void tell(){
print(std::bind(&Foo::sayHello, this));
}
};
int main(){
auto foo = Foo();
foo.tell();
}