In my C++ project I decided to give the new++ features a try. One of those features is the binding of a function with std::function via std::bind.
Now I came to a use case, where I have to rebind the std::function.
Consider the following simplified code:
class Test
{
public:
void first()
{
second(bind(&Test::third, this));
}
void second(function<void()> fun)
{
Test *other = new Test();
fun->rebindLastParameter(other); // How can I do this?
fun();
}
void third()
{
// This is called in context of "other"
}
}
How can I do the fun->rebindLastParameter(other); part (replace this pointer with other)?
(EDIT) Context:
In my application there are several classes which inherit from a class called BaseModel. Those classes are automatically transpiled from a self made description language. The following class represents a simple "asteroid" which consists of two other "asteroids":
#pragma once
#include "BaseModel.h"
#include <functional>
using namespace std;
using namespace std::placeholders;
class Test : public BaseModel
{
public:
Test(const OBB& start_obb) : BaseModel(start_obb) {}
void __init() {
scene();
}
void scene() {
combine(bind(&Test::asteroid, this),bind(&Test::asteroid, this));
}
void asteroid() {
translate(random_float(),random_float(),random_float());
sphere(7);
repeat(400,bind(&Test::impact, this));
}
void impact() {
auto p1 = random_surface_point();
select_sphere(p1,random_float() * 2 + 1,1.0);
normalize(p1);
translate_selection(-p1 * random_float() * 0.4);
}
};
The problem lies in the function BaseModel::combine, that combines (via constructive solid geometry) two new objects (1st asteroid and 2nd asteroid):
void BaseModel::combine(function<void()> left, function<void()> right)
{
BaseModel *leftModel = (BaseModel*) ::operator new (sizeof(BaseModel));
BaseModel *rightModel = (BaseModel*) ::operator new (sizeof(BaseModel));
leftModel->initWithStartOBB(*this->obb);
rightModel->initWithStartOBB(*this->obb);
auto newLeft = bind(left, leftModel); // This does not work
auto newRight = bind(right, rightModel); // This does not work
newLeft();
newRight();
// ... CSG stuff
}
As leftModel and rightModel have to be new models of the same class, I need to rebind the first parameter I previously give in my automatically transpiled class Test::scene.
Perhaps I'm on the wrong track. I hope that additional context could explain why I've run into that problem.
As #tobi303 and others have noted, your function signature for the argument of second is too constrained, as it takes a nullary function. There is nothing to rebind - it doesn't take any parameters.
In order to achieve something like it looks like you're trying to do, you need to have the argument of second be less constricted. There are several ways of doing so (making it take a function, or a pointer to a member function); the following shows it template-parameterized by a function that takes a unary argument:
#include <functional>
using namespace std;
class Test
{
public:
void first()
{
second([](Test *p){p->third();});
}
template<class Fn>
void second(Fn fn)
{
Test *const other = new Test();
fn(other);
}
void third()
{
// This is called in context of "other"
}
};
int main()
{
Test t;
t.first();
}
Personal viewpoint (one that earned me several downvotes): I think the use of many libraries and techniques, most cases of bind for sure, most cases of function - simply precede current lambda functions, and there is less and less of a need for them.
How can I do the fun->rebindLastParameter(other); part (replace this pointer with other)?
You can't, in general.
std::function relies on type-erasure which means the original type of the object that was stored in the std::function is not part of the type, and not easily accessible.
If you know for certain that the fun definitely stores an object returned by bind(&Test::third, this) then there's no need to rebind the argument, just modify fun to hold a completely different function object with the right argument, i.e.
fun = bind(&Test::third, other);
If you know it definitely stores an object returned by bind( &Test::???, other) where &Test::??? is any member function with exactly the same signature as Test::third then you could do something like this:
using binder_type = decltype(bind(&Test::third, this));
if (auto target = fun.target<binder_type>())
{
// *target is the result of the bind() expression
}
But there's still no way to modify the object at *target to replace the Test* pointer it holds.
If you know the set of functions that could have been used then you could do:
using binder_foo_type = decltype(bind(&Test::foo, this));
using binder_bar_type = decltype(bind(&Test::bar, this));
using binder_baz_type = decltype(bind(&Test::baz, this));
if (fun.target<binder_foo_type>())
{
fun = std::bind(&Test::foo, other);
}
else if (fun.target<binder_bar_type>())
{
fun = std::bind(&Test::bar, other);
}
else if (fun.target<binder_baz_type>())
{
fun = std::bind(&Test::baz, other);
}
But these are not general purpose solutions and not very maintainable.
std::mem_fn is what you are looking for, as it generates wrapper objects for pointers to members.
std::function<void(Test*)> f = std::mem_fn(&Test::third);
f(this);
Test *other = new Test();
f(other);
With std::bind, use fun with a reference to Test object. This way you can call it with a new object
void second(std::function<void(const Test&)> fun)
{
Test *other = new Test();
fun(*other);
}
Or with this object
fun(*this);
Related
I have three methods and all of them returns a string, I want to run all of them using QtConcurrent and get their return into a single list or something like that. QtConcurrent::mapped is ideal as it returns an iterator but I can only run one method at time.
In JavaScript there's promise.all([method_a, method_b, method_c]), it will automatically merge their return into a single result (iterator).
How to do that in Qt?
Since you have several methods to call, you can pass them as a sequence of functors as the first argument to QtConcurrent::mapped. The mapping functor would be an apply functor that takes a functor representing the method call and returns the result of invoking it.
First, let's have our class:
// https://github.com/KubaO/stackoverflown/tree/master/questions/concurrent-combine-49802153
#include <QtConcurrent>
#include <functional>
#include <initializer_list>
#include <type_traits>
class Cls {
public:
QString method1() const { return QStringLiteral("10"); }
QString method2() const { return QStringLiteral("20"); }
QString method3() const { return QStringLiteral("30"); }
};
The apply_t functor invokes the method passed to it as an argument:
template <class Method> struct apply_t {
using result_type = typename std::result_of_t<Method()>;
auto operator()(Method method) {
return method();
}
};
Let's make it convenient to make such applicators from the type of a sequence of functors to be called:
template <class Sequence, class A = apply_t<typename std::decay_t<Sequence>::value_type>>
A make_apply(Sequence &&) { return {}; }
For convenience, we'll also have a vector generator in the spirit of e.g. make_unique, etc.:
template <class T> QVector<T> make_vector(std::initializer_list<T> init) {
return {init};
}
Then, the problem becomes fairly simple. First, we make a vector of bound methods that will be called. Then we pass the methods to call, as well as the applicator to operate on them, to QtConcurrent::mapped. The results() gives a list of all results of the method calls, in sequence.
int main() {
Cls obj;
auto const methods = make_vector({
std::bind(&Cls::method1, &obj),
std::bind(&Cls::method2, &obj),
std::bind(&Cls::method3, &obj)
});
QFuture<QString> result =
QtConcurrent::mapped(methods, make_apply(methods));
Q_ASSERT((result.results() == QStringList{"10", "20", "30"}));
}
Instead of making a custom apply_t class, we could use a lambda, wrapped to provide the result_type member type that QtConcurrent::mapped expects. See this answer for details of wrapping the lambda. The rest of this answer provides examples of such wrapping.
Since there's no built in way to do that, you can work out a class on your own to keep futures together and return a collection of results when all tasks completed. The only limitation, here, is due to the strongly typed nature of c++: each future returned by QtConcurrent::run holds the called function result, the type of which is given at compile time, as the QFuture template parameter. What if the return types of the called functions differ from each other? In the example I provide, they all return the same type, but I think one could use QVariant for that mean and get away with it.
In a promise.h:
#ifndef PROMISE_H
#define PROMISE_H
#include <QtConcurrent/QtConcurrentRun>
#include <QFutureWatcher>
class PromiseInterface
{
public:
virtual ~PromiseInterface() = default;
virtual void finished(int id) = 0;
};
class Watcher : public QObject
{
Q_OBJECT
int _id;
PromiseInterface * _promise;
public slots:
void finished()
{
_promise->finished(_id);
deleteLater();
}
public:
Watcher(int id, PromiseInterface * promise)
: _id(id),
_promise(promise)
{}
};
template <typename T>
class Promise : public PromiseInterface
{
friend class Watcher;
void finished(int id) override
{
_resolved++;
_results[id] = _watchers[id]->result();
delete _watchers[id];
if(_resolved == _results.size())
{
if(_callback != nullptr)
{
_callback(_results);
}
}
}
QList<QFutureWatcher<T> *> _watchers;
QVector<T> _results;
void (*_callback)(QVector<T>);
int _resolved;
public:
Promise(QList<QFuture<T>> futures)
{
_resolved = 0;
_callback = nullptr;
_results.resize(futures.size());
int i=0;
for(auto f : futures)
{
QFutureWatcher<T> * watcher = new QFutureWatcher<T>();
watcher->setFuture(f);
QObject::connect(watcher, &QFutureWatcher<T>::finished, new Watcher(i++, this), &Watcher::finished);
_watchers.append(watcher);
}
}
void then(void (*callback)(QVector<T>)) { _callback = callback; }
};
#endif // PROMISE_H
The Promise class is a class template with a single template parameter that matches the one of QFuture. The observed futures are passed in the constructor, while the then method accepts a the completion callback as its only argument.
The Watcher class provides a slot to catch QFutureWatcher::finished' signals. Each instance knows the promise object through a pointer to itsPromiseInterfaceand will callfinished` from the slot, passing in the id of the future that completed.
When all futures finished, the callback function is called with the vector of results passed in.
In a very simple usage example, we can execute this function concurrently:
#include <unistd.h>
int f(int r) { sleep(1); return r;}
and pass this callback to the promise then:
void callback(QVector<int> results)
{
qDebug() << results;
}
Our main:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QList<QFuture<int>> futures = {
QtConcurrent::run(&f, 1),
QtConcurrent::run(&f, 2),
QtConcurrent::run(&f, 3)
};
Promise<int> promise(futures);
promise.then(callback);
return a.exec();
}
After about a second, this is the expected output:
QVector(1, 2, 3)
Just in case one wonders why I put in three classes, instead of making Promise extend QObject directly, and implement the finished slot itself: Qt is not letting me do that. When the Q_OBJECT macro is added to a class template, an explicit compiler error will prompt: Template classes not supported by Q_OBJECT.
The method you're looking for is QFuture::results():
QList<T> QFuture::results() const
Returns all results from the future. If the results are not
immediately available, this function will block and wait for them to
become available.
Expanding from Qt's own QtConcurrent::mapped example:
QImage scaled(const QImage &image)
{
return image.scaled(100, 100);
}
QList<QImage> images = ...;
QList<QImage> thumbnails = QtConcurrent::mapped(images, scaled).results();
I know AsyncFuture is a c++ library that converts calls into a QFuture type and uses it like a Promise object in Javascript (Combine multiple futures with different type into a single future object). unfortunately i never used it! but there are details on this reference Qt Blog Multithreaded Programming with Future & Promise
I am trying to implement lazy initializing in C++ and I am searching for a nice way to call the Initialize() member function when some other method like object->GetName() gets called.
Right now I have implemented it as follows:
class Person
{
protected:
bool initialized = false;
std::string name;
void Initialize()
{
name = "My name!"; // do heavy reading from database
initialized = true;
}
public:
std::string GetName()
{
if (!initialized) {
Initialize();
}
return name;
}
};
This does exactly what I need for the time being. But it is very tedious to setup the initialized check for every method, so I want to get rid of that. If someone knows a nice way in C++ to improve this above example, I would like to know!
Could maybe operators be used to achieve calling Initialize() when using -> for example?
Thanks!
Sounds like a job for templates! Create a lazily_initialized wrapper that takes a type T and a function object TInitializer type:
template <typename T, typename TInitializer>
class lazily_initialized : TInitializer
{// ^^^^^^^^^^^^^^
// inheritance used for empty-base optimization
private:
T _data;
bool _initialized = false;
public:
lazily_initialized(TInitializer init = {})
: TInitializer(std::move(init))
{
}
T& get()
{
if(!_initialized)
{
static_cast<TInitializer&>(*this)(_data);
_initialized = true;
}
return _data;
}
};
You can the use it as follows:
struct ReadFromDatabase
{
void operator()(std::string& target) const
{
std::cout << "initializing...\n";
target = "hello!";
}
};
struct Foo
{
lazily_initialized<std::string, ReadFromDatabase> _str;
};
Example:
int main()
{
Foo foo;
foo._str.get(); // prints "initializing...", returns "hello!"
foo._str.get(); // returns "hello!"
}
example on wandbox
As Jarod42 mentioned in the comments, std::optional<T> or boost::optional<T> should be used instead of a separate bool field in order to represent the "uninitialized state". This allows non default-constructible types to be used with lazily_initialized, and also makes the code more elegant and safer.
As the former requires C++17 and the latter requires boost, I used a separate bool field to make my answer as simple as possible. A real implementation should consider using optional, using noexcept where appropriate, and also consider exposing a const-qualified get() that returns a const T&.
Maybe call it in the constructor?
Edit: Uh, i missed the point of your question sorry.
What about a lazy factory initialization?
https://en.wikipedia.org/wiki/Lazy_initialization#C.2B.2B
Let's suppose I have the following function interface:
void giveme(void (*p)());
That function simply accepts a pointer to a function with no return type and argument.
I'm wondering if exists a way (without change the interface) to pass a class method as parameter of that function.
I'll try to explain better with an example. I have a class, like:
class Foo {
public:
template<typename T>
void bar();
};
I want to pass bar<T> (of an addressable instance of the class) as parameter of the function giveme.
I thought to bind the method with an object, and obtain the function target.
Something like:
int main(int argc, char *argv[]) {
Foo foo;
std::function<void()> f = std::bind(&Foo::bar<int>, &foo);
giveme(f.target<void()>());
return 0;
}
It compiles, but obviously does not work because, from here:
TargetType shall match the target type, so that typeid(TargetType)==target_type(). Otherwise, the function always returns a null pointer.
So, if exists, what is a way to achieve it?
Here's one (very bad) idea:
Foo * foo_ptr; // maybe thread_local
void foo_call()
{
foo_ptr->bar<int>();
}
int main()
{
Foo foo;
foo_ptr = &foo;
give_me(&foo_call);
}
It's not pretty, but neither is your situation.
There's only one way I know of, and it's a terrible idea, and don't do this.
typedef void (*void_fn)();
struct stateful_void_fn_data = {
void_fn raw;
std::function<void()> actual;
std::atomic_bool in_use;
}
// a global array to hold your function bindings and such
extern stateful_void_fn_data stateful_functions[5];
// N stateless functions that defer to the correct global state
template<int n> void void_fn_impl() {stateful_functions[n].actual();}
extern stateful_void_fn_data stateful_functions[5] =
{{void_fn_impl<0>}, {void_fn_impl<1>}, {void_fn_impl<2>}, {void_fn_impl<3>}, {void_fn_impl<4>}};
// function to register a stateful and get a stateless back
void_fn allocate_void_fn(std::function<void()>&& f) {
for(int i=0; i<5; i++) {
if(stateful_functions[i].in_use.compare_exchange_weak(false, true)) {
stateful_functions[i].actual = std::move(f);
return stateful_functions[i].raw;
}
}
throw std::runtime_error("ran out of stateful functions :(");
}
// function to unregister
void free_void_fn(void_fn f) {
if (f == nullptr) return;
for(int i=0; i<5; i++) {
if (stateful_functions[i].raw == f) {
stateful_functions[i].in_use = false;
return;
}
}
throw std::runtime_error("unknown void function");
}
Basically, I generate 5 void() functions (void_fn_impl<N>), and each calls a function stored in one of the five a global array slots (stateful_functions[i].actual). Then, allocate_void_fn will store any std::function<void()> in the global array, and hand you the void() that calls that entry in the array. This function itself is stateless, because we've stored all the state in the global array. free_void_fn and in_use exist solely to make the functions reusable.
And of course, because RAII is good:
class hidden_state_void_fn {
void_fn raw;
public:
hidden_state_void_fn(std::function<void()>&& f)
:raw(allocate_void_fn(std::move(f)) {}
hidden_state_void_fn(const hidden_state_void_fn&& r) {
raw = r.raw;
r.raw = nullptr;
}
hidden_state_void_fn& operator=(const hidden_state_void_fn&& r) {
free_void_fn(raw);
raw = r.raw;
r.raw = nullptr;
}
~hidden_state_void_fn() {free_void_fn(raw);}
operator void_fn() {return raw;}
operator()() {raw();}
};
std::map<int,std::function<void()>> tasks;
template<int n>
struct task_wrapper{
static void f(){ if (tasks.count(n)) tasks[n](); }
task_wrapper(std::function<void()> fin){ tasks[n]=fin; }
~task_wrapper(){ tasks.erase(n); }
static std::shared_ptr< void(*)() > make(std::function<void()> fin){
auto self=std::make_shared<task_wrapper>(fin);
return { &f, fin };
}
};
A task_wrapper<N>::make(func) return a shared pointer to a stateless function pointer that will call the stateful func.
We can use the the usual techniques to create an array of K function pointers of signature shared_ptr<void(*)()>(*)(). Then we can have a shared_ptr<void(*)()> register_func( std::function<void()> ).
To find blanks, we can either do a linear search, or we could build a table of blanks. This could look like a traditional allocation/free "heap", or a range-tree of blanks, or whatever.
Another approach would be to literally create and save a DLL on the fly then load it and call the symbol. This could be done via hacks (have such a DLL and a known offset to modify, copy and write, then load and run) or by shipping a C++ compiler (or other compiler) with your code (!).
I want to implement a manager that stores callbacks to member functions of polymorphic classes using C++11. The issue is that I am not sure how to handle the case where the object that the member belongs to gets deleted or should be deleted and I want to make the interface as simple as possible.
So I thought of the following: Store a std::weak_ptr to the object as well as a std::function to the member.
The following seems to work:
class MyBase {
public:
MyBase() {}
virtual ~MyBase() {}
};
//--------------------------------------------------
class MyClass : public MyBase {
public:
MyClass() : MyBase() {}
void myDouble(double val) const { std::cout << "Value is: " << val << std::endl; }
};
//--------------------------------------------------
Class Manager {
public:
void setFunction(std::weak_ptr<MyBase> base, std::function<void(double)> func) {
m_function.first = base;
m_function.second = func;
}
private:
std::pair<std::weak_ptr<MyBase>, std::function<void(double)>> m_function;
};
To use this:
Manager db;
std::shared_ptr<MyClass> myClass = std::make_shared<MyClass>();
db.setFunction(myClass, std::bind(&MyClass::myDouble, myClass, std::placeholders::_1));
Now I want to hide the std::bind part from the user, so that he only needs to call:
db.setFunction(myClass, &MyClass::myDouble);
So I want to get almost the following working in my manager function:
void setFunc2(std::weak_ptr<MyBase> base, std::function<void(double)> func) {
m_function.first = base;
m_function.second = std::bind(func, base, std::placeholders::_1);
}
But the above gives errors:
error: no match for 'operator=' (operand types are 'std::function<void(double)>' and
'std::_Bind_helper<false, std::function<void(double)>&, std::weak_ptr<MyBase>&, const std::_Placeholder<1>&>::type {aka std::_Bind<std::function<void(double)>(std::weak_ptr<MyBase>, std::_Placeholder<1>)>}')
m_function.second = std::bind(func, base, std::placeholders::_1);
Is there a better way to do this, or perhaps a way to get this working?
Something interesting that I notice. If I use the std::shared_ptr the use_count() gets incremented with the call to std::bind in the original code. Thus I can not manually reset/destroy the object unless I unset the member on my manager. Where is this behaviour documented, I normally use cppreference?
I have looked at the following question but can't seem to get it working for my problem: How can I use polymorphism with std::function?
Template setFunction so that you can accept pointer-to-member-of-derived, and don't have to write 12 overloads for the combinations of cv/ref qualifiers.
template<class D, class D2, class F>
void setFunction(const std::shared_ptr<D> &sp, F D2::* member) {
// optionally static_assert that D2 is a base of D.
m_function.first = sp;
m_function.second = std::bind(member, sp.get(), std::placeholders::_1);
}
Obviously you need to make sure you lock() m_function.first before calling m_function.second.
Alternatively, just use a lambda that captures both the weak_ptr and the member function pointer:
std::function<void(double)> m_function;
template<class D, class D2, class F>
void setFunction(const std::shared_ptr<D> &sp, F D2::* member) {
std::weak_ptr<D> wp = sp;
m_function = [wp, member](double d) {
if(auto sp = wp.lock()){
((*sp).*member)(d);
}
else {
// handle pointer no longer valid case.
}
};
}
I like decoupling my listener/broadcaster from the implementation of the listener.
This means I cannot place requirements on the listener. It cannot require the listener be allocated in a particular way.
The easiest method I have found is to have the broadcaster return a token whose lifetime determines the lifetime of the connection.
using token = std::shared_ptr<void>;
template<class...Args>
struct broadcaster {
using target = std::function<void(Args...)>;
using wp_target = std::weak_ptr<target>;
using sp_target = std::shared_ptr<target>;
static sp_target wrap_target( target t ) {
return std::make_shared<target>(std::move(t));
};
token start_to_listen( target f ) {
auto t = wrap_target(std::move(f));
targets.push_back(t);
return t;
}
void broadcast( Args... args ) {
targets.erase(
std::remove_if( targets.begin(), targets.end(),
[&]( wp_target t )->bool { return t.expired(); }
),
targets.end()
);
auto targets_copy = targets; // in case targets is modified by listeners
for (auto wp : targets_copy) {
if (auto sp = wp.lock()) {
(*sp)(args...);
}
}
}
std::vector<wp_target> targets;
};
this forces people who register listeners to keep std::shared_ptr<void> around.
We can even make it fancier, where the destruction of the last shared_ptr<void> actually removes the listener from the list immediately. But the above lazy deregistration seems to work reasonably well in my experience, and it is relatively easy to make it multi-thread friendly. (one serious problem is what happens when a broadcast event removes or adds things to the list of listeners: adapting the above for it to work is nice and easy with the rule that listeners added when broadcasting do not get the broadcast, and listeners removed during broadcasting do not get the broadcast. Listeners removed concurrently during broadcast can get the broadcast in most of my implementations... That gets expensive to avoid.)
We could instead decouple it differently. The listener could pass a std::function and a std::weak_ptr separately to the broadcaster, who stores both and only calls the std::function if the std::weak_ptr is valid.
I like Yakk's approach. Here's an updated version that fixes a few compile issues (e.g. cannot name function 'register'). It also adds a rm_callback method for clients to easily remove their registration without forcing their registration token to go out of scope or knowing the internals. I didn't like scanning the list every time an event was broadcast so I added a deleter on the shared pointer which does the cleanup task. All new bugs introduced or inefficiencies are mine. The alert reader should be aware of threading issues when modifying the list while broadcasting...
using token = std::shared_ptr<void>;
template<class...Args>
struct broadcaster {
using target = std::function<void(Args...)>;
using wp_target = std::weak_ptr<target>;
using sp_target = std::shared_ptr<target>;
token add_callback(target f) {
sp_target t(new target(std::move(f)), [&](target*obj) { delete obj; cleanup(); });
targets.push_back(t);
return t;
}
static void rm_callback(token& t)
{
t.reset();
}
void cleanup()
{
targets.erase(
std::remove_if(targets.begin(), targets.end(),
[](wp_target t) { return t.expired(); }
),
targets.end()
);
}
void broadcast(Args... args) {
for (auto wp : targets) {
if (auto sp = wp.lock()) {
(*sp)(args...);
}
}
}
std::vector<wp_target> targets;
};
// declare event taking a string arg
broadcaster<std::string> myEvent;
I have a functioning C++ callback function, triggered by a user 'mouse down' event. (The IDE is VS2010.)
With each call, I'd like to increment a simple count variable that is local to the callback's scope. Simply put, what is the 'best practices' way to do this?
Thanks in advance for any opinions or directives.
Replace your callback function with a functor - they can store state. An example functor:
#include <iostream>
#include <memory>
class Functor
{
private:
std::shared_ptr<int> m_count;
public:
Functor()
: m_count(new int(0))
{}
void operator()()
{
++(*m_count);
// do other stuff...
}
int count() const
{
return *m_count;
}
};
template <typename F>
void f(F callback)
{
// do stuff
callback();
// do other stuff
}
int main()
{
Functor callback;
f(callback);
f(callback);
std::cout << callback.count(); // prints 2
return 0;
}
Note the use of a shared_ptr inside the functor - this is because f has a local copy of the functor (note the pass-by-value) and you want that copy to share its int with the functor to which you have access. Note also that f has to take its argument by value, since you want to support all callables, and not just functors.