Please refer the following code snippet. I want to use the std::bind for overloaded function foobar. It calls only the method with no arguments.
#include <functional>
#include <iostream>
class Client
{
public :
void foobar(){std::cout << "no argument" << std::endl;}
void foobar(int){std::cout << "int argument" << std::endl;}
void foobar(double){std::cout << "double argument" << std::endl;}
};
int main()
{
Client cl;
//! This works
auto a1 = std::bind(static_cast<void(Client::*)(void)>(&Client::foobar),cl);
a1();
//! This does not
auto a2= [&](int)
{
std::bind(static_cast<void(Client::*)(int)>(&Client::foobar),cl);
};
a2(5);
return 0;
}
You need to use placeholders for the unbound arguments:
auto a2 = std::bind(static_cast<void(Client::*)(int)>(&Client::foobar), cl,
std::placeholders::_1);
a2(5);
You can also perform the binding with a lambda capture (note that this is binds cl by reference, not by value):
auto a2 = [&](int i) { cl.foobar(i); };
Related
Is there anyway to check if a generic lambda is callable with a specific type?!
#include <iostream>
#include <type_traits>
struct A { void DoAStuff() {} };
struct B { void DoBStuff() {} };
int main() {
auto fn = [](auto& arg) { arg.DoAStuff(); };
std::cout << std::boolalpha << std::is_invocable<decltype(fn), A&>::value << std::endl;
std::cout << std::boolalpha << std::is_invocable<decltype(fn), B&>::value << std::endl;
}
this code doesn't compile and I understand why. but I am wondering if there is anyway to get something like this to work? like we can define a class than when passed the lambda, return false instead of compilation error
error: no member named 'DoAStuff' in 'B'
I have the following code:
#include <iostream>
class Bobo
{public:
int member;
void function()
{
auto lambda = [this]() { std::cout << member << '\n'; };
auto lambda2 = [this]() { std::cout << typeid(*this).name() << '\n'; };
lambda();
lambda2();
}
};
int main()
{
Bobo bobo;
bobo.function();
}
The line std::cout << typeid(*this).name(); in lambda2() understandably prints out:
class <lambda_49422032c40f80b55ca1d0ebc98f567f>
However how can I access the 'this' pointer that's been captured so the typeid operator can return type class Bobo?
Edit: The result I get is from compiling this code in Visual Studio Community 2019.
This seems to be VS's bug; when determining the type of this pointer in lambda:
For the purpose of name lookup, determining the type and value of the
this pointer and for accessing non-static class members, the body of
the closure type's function call operator is considered in the context
of the lambda-expression.
struct X {
int x, y;
int operator()(int);
void f()
{
// the context of the following lambda is the member function X::f
[=]()->int
{
return operator()(this->x + y); // X::operator()(this->x + (*this).y)
// this has type X*
};
}
};
So the type of this should be Bobo* in the lambda.
As #songyuanyao suggests, your could should work and produce the appropriate typeid, so it's probably a bug. But - here's a workaround for you:
#include <iostream>
class Bobo
{public:
int member;
void function() {
auto lambda = [this]() { std::cout << member << '\n'; };
auto lambda2 = [my_bobo = this]() {
std::cout << typeid(std::decay_t<decltype(*my_bobo)>).name() << '\n';
};
lambda();
lambda2();
}
};
int main() {
Bobo bobo;
bobo.function();
}
Note that you can replaced typeid(...).name() with the proper type name, obtained (at compile-time!) as per this answer:
std::cout << type_name<std::decay_t<decltype(*my_bobo)>>() << '\n';
I'm working on a mechanism for creating "safe" callbacks, that won't cause undefined behavior when called after their parent object has been destroyed. The class should be generic enough to be able to wrap any callback, with void(...) callbacks simply being executed or not, depending on the status of the object that they are bound to, and callbacks that return a value returning a boost::optional with the returned value, if executed, or boost::none if not executed.The implementation is almost complete, but there are 2 things that make me worried that I don't fully understand my code...
If line 19 is uncommented and 18 commented out, the template won't compile - is this merely a syntactic problem that can be solved, or am I trying to use the result_of mechanism incorrectly (does the std::forward there change the semantics or is it superfluous?)
If line 88 is uncommented and 89 commented out, the compilation results in failure due to ambiguousness of the function call to fun, which I don't quite understand - it seems to me that fun(int&&) is an exact match, so why does the compiler complain of ambiguousness with fun(int) version?
If there are other subtle (or gross) errors, please comment as well.
Thanks.
#include <iostream>
#include <string>
#include <type_traits>
#include <utility>
#include <memory>
#include <boost/optional.hpp>
template<class Func>
class SafeCallback
{
public:
SafeCallback(std::shared_ptr<bool> guard, const Func& callback)
: guard_(guard)
, callback_(callback)
{}
template<class... Args>
// auto operator()(Args&&... args) -> typename std::enable_if<std::is_void<typename std::result_of<Func(std::forward<Args>(args)...)>::type>::value, // won't compile with: 19:91: error: invalid use of template-name 'std::result_of' without an argument list
auto operator()(Args&&... args) -> typename std::enable_if<std::is_void<typename std::result_of<Func(Args...)>::type>::value,
void>::type
{
std::cout << "trying void callback" << std::endl;
if(guard_.lock())
{
std::cout << "callback is still alive :)" << std::endl;
callback_(std::forward<Args>(args)...);
return;
}
std::cout << "uh-oh, callback is dead!" << std::endl;
}
template<class... Args>
auto operator()(Args&&... args) -> typename std::enable_if<!std::is_void<typename std::result_of<Func(Args...)>::type>::value,
boost::optional<typename std::result_of<Func(Args...)>::type>>::type
{
std::cout << "trying non-void callback" << std::endl;
if(guard_.lock())
{
std::cout << "callback is still alive :)" << std::endl;
return callback_(std::forward<Args>(args)...);
}
std::cout << "uh-oh, callback is dead!" << std::endl;
return boost::none;
}
bool isAlive()
{
return guard_.lock();
}
private:
std::weak_ptr<bool> guard_;
Func callback_;
};
class SafeCallbackProvider
{
public:
SafeCallbackProvider()
: guard_(new bool(true))
{}
virtual ~SafeCallbackProvider() = default;
template<class Func>
SafeCallback<Func> makeSafeCallback(const Func& callback)
{
return SafeCallback<Func>(guard_, callback);
}
private:
std::shared_ptr<bool> guard_;
};
struct A : SafeCallbackProvider
{
void fun()
{
std::cout << "---this is fun---" << std::endl;
}
int fun(int&& i)
{
std::cout << "&& this is && " << i << " && fun &&" << std::endl;
return i;
}
// int fun(int i) // fails to compile with: 123:48: error: call of overloaded 'fun(int)' is ambiguous
int fun(int& i)
{
std::cout << "---this is ---" << i << "--- fun---" << std::endl;
return i;
}
};
int main()
{
A* a= new A;
auto cb = a->makeSafeCallback(
[&]()
{
a->fun();
});
cb();
delete a;
cb();
std::cout << "\n----------\n\n";
A* a2= new A;
auto cb2 = a2->makeSafeCallback(
[&](int i)
{
return a2->fun(i);
});
cb2(5);
delete a2;
cb2(5);
std::cout << "\n----------\n\n";
A* a3= new A;
auto cb3 = a3->makeSafeCallback(
[&](int&& i)
{
return a3->fun(std::forward<int>(i));
});
cb3(5);
delete a3;
cb3(5);
return 0;
}
Note: this only answers the first question, because I apparently have the attention span of a fly. More coming soon.
std::result_of essentially performs some magic based on a function type that looks like a function call. In the line that works:
typename std::result_of<Func(Args...)>::type
This is the intended use, simulating the call of an instance of Func with values of types Args.... On the other hand:
typename std::result_of<Func(std::forward<Args>(args)...)>::type
This expands Args and args into a group of values, which then form a chain of ,-operators inside a functoin-style cast to Func. The whole thing is an expression instead of the type std::result_of expects.
It looks like you're halfway to using decltype instead, which would look like:
decltype(std::declval<Func&>()(std::forward<Args>(args)...))
... or, if you can be bothered to move it underneath callback_'s declaration:
decltype(callback_(std::forward<Args>(args)...))
Rules of Overloading are that .
Signature of function should be different.
In both the case compiler is finding same signature, try to change the signature and see the result.
I have faced with a problem of passing method to method in C++. What I am trying to do is to reduce amount of code, which is almost the same for several methods.
For example, I have next code:
class F_test {
public:
void f1() {
std::cout << "f1" << std::endl;
}
void f2() {
std::cout << "f2" << std::endl;
}
void foo_main(std::string str, std::function<void(void)> const &f) {
std::cout << "some actions before" << std::endl;
std::cout << str << std::endl;
f();
std::cout << "some actions after" << std::endl;
}
void f1(std::string s1) {
std::function <void(void)> m1 = F_test::f1;
foo_main("processing f1", m1);
}
void f2(std::string s2) {
std::function <void(void)> m2 = F_test::f2;
foo_main("processing f2", m2);
}
};
As for processing f1 and f2 methods I need to perform some the same operations, I have decided to created one method (foo_main) with these operations and pass needed function (f1 or f2) to it, rather than create two separate methods with code duplication.
But, these code is failed on compilation with:
'F_test::f1': function call missing argument list; use '&F_test::f1' to create a pointer to member
'F_test::f2': function call missing argument list; use '&F_test::f2' to create a pointer to member
If to write &F_test::f1 and &F_test::f2, another compilation error is happened:
'void std::_Func_class<_Ret,>::_Set(std::_Func_base<_Ret,> *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base<_Ret,> *'
Non-static member functions need an object to be called with. You can't just call f1() without an instance of F_test. The compile error results from you trying to do that.
To create a null ary function out of member function, you need to bind an instance to it, whether via std::bind:
std::function <void()> m1 = std::bind(&F_test::f1, this);
or a lambda:
std::function <void()> m1 = [this]{ f1(); };
Note that bind doesn't work in this case since you have overloaded the name f1. It would work in the general case though. The lambda will work regardless.
The simpler would be to use lambda:
F_test test;
test.foo_process("string", [&](){test.f1();});
Else to select (in std::bind) overload f1() whereas other overloads exist (as f1(std::string)), you have to specify which one you want:
static_cast<void (F_test::*)()>(&F_test::f1)
If you don't want to use lambda by some reasons, then you should rewrite the code like:
class F_test {
public:
void f1impl() const {
std::cout << "f1" << std::endl;
}
void f2impl() const {
std::cout << "f2" << std::endl;
}
void foo_process(std::string str, std::function<void(const F_test&)> const &f) {
std::cout << "some actions before" << std::endl;
std::cout << str << std::endl;
f(*this);
std::cout << "some actions after" << std::endl;
}
void f1(std::string s1) {
std::function<void(const F_test&)> f = &F_test::f1impl;
foo_process("processing f1", f);
}
void f2(std::string s2) {
std::function <void(const F_test&)> m2 = &F_test::f2impl;
foo_process("processing f2", m2);
}
};
you can't use a member function pointer to initialize a std::function. Use a lambda instead.
void f1(std::string s1) {
auto m1 = [this](){ f1(); };
foo_main("processing f1", m1);
}
I'm trying to create an example of binding a boost::function to a member function that goes out of scope. It is still possible to call this function, even though the object no longer exists.
I need to prove that it is not a correct use and the app needs to fail. But the memory location still seems to be in tact, so I need a way to make it fail.
The other question asked would be: am I right? Is there something I might be missing?
class bad_object {
public:
void fct1() {cout << "Fct 1 called. String value: " << sth << endl;};
void fct2(int i) {cout << "Fct 2 with param " << i << endl;};
string sth;
};
int main()
{
bad_object b;
boost::function<void ()> f1(boost::bind( &bad_object::fct1, b ));
boost::function<void ()> f2(boost::bind( &bad_object::fct2, b, 10 ));
boost::function<void ()> f3;
{
bad_object c;
c.sth = "There once was a cottage";
f3 = boost::bind( &bad_object::fct1, c );
}
// c now goes of scope, f3 should therefore be invalid
f3();
return 0;
}
output as expected.
Fct 1 called. String value:
Fct 2 with param 10
Fct 1 called. String value: There once was a cottage
Perhaps you use weak_ptr: Live On Coliru
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
struct X
{
int foo() const
{
return 42;
}
virtual ~X() {
std::cout << "I'm stepping out here\n";
}
};
int weak_call(int (X::*ptmf)() const, boost::weak_ptr<X> const& wp)
{
auto locked = wp.lock();
if (!locked)
throw boost::bad_weak_ptr();
return ((*locked).*ptmf)();
}
int main()
{
boost::function<int()> bound_foo;
{
auto x = boost::make_shared<X>();
bound_foo = boost::bind(weak_call, &X::foo, boost::weak_ptr<X>(x));
std::cout << "Bound foo returns: " << bound_foo() << "\n";
}
std::cout << "Bound foo returns: " << bound_foo() << "\n";
}
Prints:
Bound foo returns: 42
I'm stepping out here
terminate called after throwing an instance of 'boost::bad_weak_ptr'
what(): tr1::bad_weak_ptr
A more generalized version (that allows n-ary member function, optionally const-qualified) is here (requiring c++11): coliru