C++ boost::bind and boost::function, class member function callbacks and operator==. What am I doing wrong? - function

I've got a problem with using boost::bind and boost::function and passing boost::function as a callback into another class.
Here's an example that is the problematic situation:
typedef boost::function<void (bool)> callbackFunction;
class HasCallback
{
public:
HasCallback() : value(0)
{
}
int value;
void CallBackFunction(bool changed)
{
std::cout << "HasCallback class. CallBackFunction called. Parameter: " << value << std::endl;
}
};
class ReceivesCallback
{
public:
void AddCallback(callbackFunction newFunc)
{
callbacks.push_back(newFunc);
}
void execute(int &i)
{
for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
{
(*it)(i++);
}
}
void RemoveHandler(callbackFunction oldFunc)
{
for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
{
if((*it) == oldFunc)
{
callbacks.erase(it);
break;
}
}
}
private:
std::vector<callbackFunction> callbacks;
};
int main()
{
HasCallback hc;
ReceivesCallback rc;
rc.AddCallback(boost::bind(&HasCallback::CallBackFunction, &hc, _1));
hc.value = 123;
HasCallback hc2;
rc.AddCallback(boost::bind(&HasCallback::CallBackFunction, &hc2, _1));
hc2.value = 321;
int a = 0;
rc.RemoveHandler(boost::bind(&HasCallback::CallBackFunction, &hc2, _1));
rc.execute(a);
}
The problem I'm having is that this doesn't even compile. It fails within ReceivesCallback::RemoveHandler in the if((*it) == oldFunc) line with the error saying that there's more than one overload of the operator== for the thing i'm trying to do.
I keep searching for this and can't find what I'm doing wrong. Also, I keep finding contradicting information, one saying that it's possible to compare boost::function-s and another saying it's not. I can see the operator== functions within boost/function_base.hpp and i believe this is supposed to work, I just can't seem to figure out how. Can someone help me out here? My suspicion is that it fails because the parameters of the boost::bind need to be specified fully(be concrete values) but this is something i cannot get in the code I'm developing, I just need to know whether the passed handler is registered or not, since I'm binding to an object it should have all the information neeeded to make the distinction.

See Boost.Function FAQ for an explanation : Why can't I compare boost::function objects with operator== or operator!= ?.
Boost.Functions only provides comparison of a boost::function with an arbitrary function object. I believe that making your RemoveHandler member function template could fix the issue :
template<class Functor>
void RemoveHandler(const Functor &oldFunc)
{
for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
{
if((*it) == oldFunc)
{
callbacks.erase(it);
break;
}
}
}
Here, oldFunc gets to keep its actual type without being 'wrapped' in a boost::function.

Related

"Failed to specialize function template" when trying to pass member function of another class

I have been trying to assign class's member function to a std::function but it throws compile time error Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)
Below is the header file of that class :
class TypeAnalysis {
public:
bool AnalysisHelper(std::string filePath);
void createTypeTable(std::string dir, std::string pattern, size_t nThread = 3);
std::vector<std::string> getFiles(std::string dir, std::vector<std::string> patterns);
private:
};
And below is createtypeTable function where I am assigning AnalysisHelper method to std::fnuction object.
void TypeAnalysis::createTypeTable(std::string dir, std::string pattern, size_t nThread)
{
Threadpool<bool, std::string> tp(10);
DataContext dc;
tp.start();
std::vector<std::string> patterns = SH::split(pattern);
std::vector<std::string> files = getFiles(dir, patterns);
std::function<bool(std::string)> w = &TypeAnalysis::AnalysisHelper; //I think issue is here
try {
if (files.size() > 0) {
for (size_t i = 0; i < files.size(); i++) {
WorkItem<bool, std::string> *wi1 = new WorkItem<bool, std::string>(&w, &files[i]);
tp.doWork(wi1);
}
}
}
catch (std::exception ex) {
std::cout << ex.what();
return;
}
tp.doWork(nullptr);
tp.wait();
DataContext::getContextThreadPool().doWork(nullptr);
}
When I tried to do the same without any class definition (AnalysisHelper was Glabal function and main had same body as createTypeTable), it worked fine.
Any idea whats wrong?
Yes, the problem is in this line:
std::function<bool(std::string)> w = &TypeAnalysis::AnalysisHelper;
I can not see this as correct operation. You are referencing a member function of a class. This member function may need to edit or read one of the member variables of that class. It is not a free function. It is part of the class which should be called for a specific object. So it is normal that C++ denied that.
Edit:
I found this https://isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr
How do I pass a pointer-to-member-function to a signal handler, X event callback, system call that starts a thread/task, etc?
Don’t.
Because a member function is meaningless without an object to invoke it on,
you can’t do this directly (if The X Window System was rewritten in
C++, it would probably pass references to objects around, not just
pointers to functions; naturally the objects would embody the required
function and probably a whole lot more)
Issue was I was not binding the method to any object. Changing
std::function<bool(std::string)> w = &TypeAnalysis::AnalysisHelper;
to
std::function<bool(std::string)> w = [=](std::string file) { return this->AnalysisHelper(file); };
worked.

How should memory be freed after an exception is thrown in C++?

I apologize if this question is a duplicate - I searched for a while, but it's possible that my Google-fu just isn't up to snuff.
I am modifying a C++ program that calls into a C library. The C library allocates a bunch of memory (using malloc()), and the C++ program uses it and then frees it. The catch is that the C++ program can throw an exception midway through execution, causing the allocated memory to never be freed.
As a (rather contrived) example:
/* old_library.c */
char *allocate_lots() {
char *mem = (char *)malloc(1024);
return mem;
}
/* my_prog.cpp */
void my_class::my_func () {
char *mem = allocate_lots();
bool problem = use(mem);
if (problem)
throw my_exception("Oh noes! This will be caught higher up");
free(mem); // Never gets called if problem is true
}
My question is: how ought I to deal with this? My first idea was to wrap the whole thing in a try/catch block, and in the catch just check and free the memory and re-throw the exception, but this seems graceless and clunky to me (and wouldn't work well if I want to actually catch an exception). Is there a better way to do it?
EDIT: I probably should have mentioned that we're using g++ 4.2.2, from back in 2007 before std::unique_ptr was introduced. Chalk it up to corporate inertia.
Use std::unique_ptr with a custom deleter that calls free:
class free_mem {
public:
void operator()(char *mem) { free(mem); }
};
void my_class::my_func() {
std::unique_ptr<char, free_mem> mem = allocate_lots();
You should make sure that you don't throw until after you have freed the memory - or that you use a suitable smart pointer structure to store the mem, such that when the throw happens, and the stack unwinds, the mem gets freed.
Wrap that rascal:
struct malloc_deleter {
template <typename T>
void operator () (T* p) const {
free(p);
}
};
void my_class::my_func () {
std::unique_ptr<char[],malloc_deleter> mem{allocate_lots()};
bool problem = use(mem.get());
if (problem)
throw my_exception("Oh noes! This will be caught higher up");
}
Since you're using an old compiler version that doesn't have unique_ptr, you can write your RAII wrapper yourself:
class ResourceWrapper {
public:
ResourceWrapper(char* ptr) : m_ptr(ptr) {}
~ResourceWrapper() { free(m_ptr); }
// whatever getters suit you, at the very least:
char* get() const { return m_ptr; }
private:
char* const m_ptr;
};
void my_class::my_func () {
ResourceWrapper mem(allocate_lots());
bool problem = use(mem.get());
if (problem)
throw my_exception("Oh noes! This will be caught higher up");
}
Just make sure not to allow copy/assignment even implicitly (which is why I made m_ptr const) or you'd risk ending up with double-freeing your memory ("move" semantics à la auto_ptr are best avoided unless you absolutely need it).
Since you can't use std::unique_ptr, you could create your own deleter class that would control the lifetime of the pointer in RAII fashion. To keep it simple this example doesn't wrap the actual pointer but exists alongside it; a safer approach would be to make a true smart pointer class.
class AutoFree
{
public:
AutoFree(void* p) : m_p(p)
{
}
~AutoFree()
{
free(m_p);
}
private:
void* m_p;
};
void my_class::my_func () {
char *mem = allocate_lots();
AutoFree mem_free(mem);
bool problem = use(mem);
if (problem)
throw my_exception("Oh noes! This will be caught higher up");
}
Is there any reason not to simply free the memory inside the if clause?
if (problem) {
free (mem);
throw my_exception ("Drat!");
}
Use unique_ptr: http://coliru.stacked-crooked.com/view?id=cd3f0fc64d99cc07a2350e2ff9686500-542192d2d8aca3c820c7acc656fa0c68
#include <stdexcept>
#include <iostream>
#include <memory>
/* old_library.c */
char *allocate_lots()
{
return static_cast<char*>(malloc(1024));
}
struct my_exception : virtual std::exception {
const char* const msg;
my_exception(const char* const msg) : msg(msg) {}
const char* what() const noexcept { return msg; }
};
struct my_class
{
struct Free { void operator() (char* p) const { free(p); } };
/* my_prog.cpp */
void my_func()
{
std::unique_ptr<char, Free> mem;
mem.reset(allocate_lots());
bool problem = use(mem.get());
if(problem)
{
throw my_exception("Oh noes! This will be caught higher up");
}
}
static bool use(char*) { return true; }
};
int main()
{
my_class prog;
prog.my_func();
}

Double linked list delete back node function

/* There is something wrong with the function delete_back(); I think something wrong with the remove function 3 parts.
Also remove_ele() I do not how to do it, thanks.
why I use the same method to delete element does not work
*/
#include <iostream>
using namespace std;
template<class T>
class doulinked
{
private:
doulinked *head;
doulinked *tail;
doulinked *prev;
doulinked *next;
T data;
public:
doulinked()
{
head=tail=prev=next=NULL;
T data;
}
void Inlist (doulinked *head);
void add(T d);
void insert_node();
void remove(doulinked* v);
void push_tail(T d);
void delete_front();
void delete_back();
void remove_ele (T d);
template <class U>
friend ostream & operator<<(ostream & os, const doulinked<U> & dll);
};
template<class U>
ostream & operator<<(ostream & os,const doulinked<U> & dll)
{
doulinked<U> * tmp = dll.head;
while (tmp)
{
os << tmp->data << " ";
tmp = tmp->next;
}
return os;
}
template<class T>
void doulinked<T>::add(T d)
{
doulinked *n = new doulinked;
n->data=d;
if( head == NULL)
{
head = n;
tail = n;
}
else
{
head->prev = n;
n->next = head;
head = n;
}
}
template<class T>
void doulinked<T>::push_tail(T d)
{
doulinked *n = new doulinked;
n->data=d;
if( tail == NULL)
{
head = n;
tail = n;
}
else
{
tail->next = n;
n->prev = tail;
tail = n;
}
}
template <class T>
void doulinked<T>::delete_front()
{
remove(head);
}
template <class T>
void doulinked<T>::delete_back()
{
remove(tail);
}
template <class T>
void doulinked<T>::remove(doulinked* v)
{
if(v->prev!=NULL && v->next!=NULL)
{
doulinked* p = v->prev;
doulinked* n = v->next;
p->next = n;
n->prev = p;
delete v;
}
else if(v->prev==NULL && v->next!=NULL)
{
doulinked* n =v->next;
head->next = n;
n->prev = head;
delete head;
head=n;
}
else if(v->prev!=NULL && v->next==NULL) // have some wrong with this loop;
{
doulinked* p=v->prev;
p->next=tail;
tail->prev=p;
delete tail;
tail=p;
}
}
template <class T>
void doulinked<T>::remove_ele(T d) // have some wrong with this loop
{
if(head->data==d)
{
remove(head);
head=head->next;
}
else
head=head->next;
}
int main()
{
doulinked<int> dll;
dll.add(5123);
dll.add(1227);
dll.add(127);
dll.push_tail(1235);
dll.push_tail(834);
dll.push_tail(1595);
dll.delete_front();
//dll.delete_back();
//dll.remove_ele(834);
cout<<dll<<endl;
system("pause");
}
Your design is a little confused.
The traditional C++ way to design a linked list (like std::list) has separate node and list classes, instead of a single class that acts as both:
template <typename T> struct node {
node *prev, *next;
};
template <typename T> struct list {
node *head, *tail;
};
If you want to just pass around node pointers, that's fine—but then you have to pass around node pointers, not node objects. And the mutator functions have to return a pointer as well—if you call delete_front on the head node, you've now got a reference to a deleted node; you need its next or you've lost any reference to the list. Since the constructor has to return a pointer, you can't use a real public constructor; you want a static factory method instead. And so on.
You also have to be consistent about whether there's a "sentinel node" before the head (and after the tail) or not. If you're creating a sentinel in your constructor—as you are doing—new nodes inserted at the end(s) need to point at the sentinel(s)—which you aren't doing.
Also, the whole head/tail notion you're using is wrong for a node API. (Also, it's incredibly confusing to mix and match names from different styles—you've got add matching delete_front and push_tail matching delete_back…) To have a push_tail method, you either have to walk the entire list (making it O(N)), or you have to have every node hold the tail pointer (making any list change O(N)), or you have to make the head hold a tail pointer and the tail hold a head pointer.
The last one works (it wastes a couple of pointers for every node when only one node needs each, but that rarely matters). But it gets confusing to think about.
It's actually a lot simpler to just create a circular list, where the head's prev points at the tail (or sentinel) instead of 0, and the tail's next points at the head (or sentinel) instead of 0. This gets you all the advantages of a separate list class, without needing that class—if you have a pointer to the head, that's all you need to refer to the entire list (because node is the head and node->prev is the tail, or or similarly if you have a sentinel).
Also, your constructor doesn't make much sense:
doulinked()
{
head=tail=prev=next=NULL;
T data;
}
This creates a local default-constructed T variable named data, and then… does nothing with it. You probably wanted to set data to something. And you probably wanted to use initializers for this. And in that case, you don't need to do anything, because that's already the default.
And I'm not sure what Inlist is even supposed to do.
As for remove_ele(T d), presumably you want to remove the first element whose data == d, right? If you write a find method first, then it's trivial: remove(find(d)). (I'm assuming that find throws an exception; if you want find to return null or the sentinel or something else instead, and remove_ele to return true or false, obviously you need one more line to check whether the find worked.)
If you don't know how to write a find method… well, that's kind of the whole point of a linked list, there's a trivial recursive definition for all traversal functions, including find:
node *node::find(T d) {
if (data == d) { return this; }
if (next) { return next->find(d); }
return 0;
}
Anyway, I think rather than try to bang on your code until it works, you should look at existing implementations of the various designs until you understand the differences, then pick the design you want and try to implement that.

QSQLTableModel inheritor and QTableView

I wrote QSQLTableModel inheritor for working with qml and it's work well. I need use it with QTableView too, data shows, but I cannot modify it - when I edit everything is ok, but all changes drop when I get out from field (I know about editStrategy, but the problem occurs earlier). I suppose that something wrong with virtual function, but I cant undestant what. If i create QSqlTableModel with the same parameters, everything is ok. Somebody have any idea how can i fix this? My code:
h:
class ListModel : public QSqlTableModel
{
Q_OBJECT
Q_PROPERTY( int count READ rowCount() NOTIFY countChanged())
signals:
void countChanged();
public:
Q_INVOKABLE QVariant data(const QModelIndex &index, int role) const;
ListModel(QObject *parent, QSqlDatabase _db):QSqlTableModel(parent,_db){this->setEditStrategy(QSqlTableModel::OnManualSubmit);}
void applyRoles();
#ifdef HAVE_QT5
virtual QHash<int, QByteArray> roleNames() const{return roles;}
#endif
private:
int count;
QHash<int, QByteArray> roles;
};
cpp:
//based on http://qt-project.org/wiki/How_to_use_a_QSqlQueryModel_in_QML
void ListModel::applyRoles()
{
roles.clear();
qDebug()<<"\n"<<this->tableName();
for (int i = 0; i < this->columnCount(); i++) {
QString role=this->headerData(i, Qt::Horizontal).toString();
roles[Qt::UserRole + i + 1] = QVariant(role).toByteArray();
qDebug()<<this->headerData(i, Qt::Horizontal);
}
#ifndef HAVE_QT5
setRoleNames(roles);
#endif
}
QVariant ListModel::data(const QModelIndex &index, int role) const{
QVariant value;
if(role < Qt::UserRole)
{
value = QSqlQueryModel::data(index, role);
}
else {
int columnIdx = role - Qt::UserRole - 1;
QModelIndex modelIndex = this->index(index.row(), columnIdx);
value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
}
return value;
}
UPD
I understood that the problem is in data method's quantifier const, if I remove it everything is ok with QTableView, but I cant get data from model with gml's listviews. I see only one solution - replace interition from QSqlTableModel with aggregation it, but maybe someone knows better solution?
Summary: Solved with strange hack - inherited from QSqlRelationalTableModel instead QSqlTableModel, I think the reason is that QSqlRelationalTableModel has rewritten non virtual method data

std::vector of std::function

I have the following:
typedef std::function<void(const EventArgs&)> event_type;
class Event : boost::noncopyable
{
private:
typedef std::vector<event_type> EventVector;
typedef EventVector::const_iterator EventVector_cit;
EventVector m_Events;
public:
Event()
{
}; // eo ctor
Event(Event&& _rhs) : m_Events(std::move(_rhs.m_Events))
{
}; // eo mtor
// operators
Event& operator += (const event_type& _ev)
{
assert(std::find(m_Events.begin(), m_Events.end(), _ev) == m_Events.end());
m_Events.push_back(_ev);
return *this;
}; // eo +=
Event& operator -= (const event_type& _ev)
{
EventVector_cit cit(std::find(m_Events.begin(), m_Events.end(), _ev));
assert(cit != m_Events.end());
m_Events.erase(cit);
return *this;
}; // eo -=
}; // eo class Event
And during compilation:
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(41): error C2451: conditional expression of type 'void' is illegal
1> Expressions of type void cannot be converted to other types
Now, I understand this is because of what is being stored in the vector and the operator ==. Is there another way to store std::function in an STL container? Do I need to wrap it up in something else?
You can store boost::function in the vector, provided you don't use std::find. Since you seem to need this, wrapping the function in its own class with equality would be probably the best.
class EventFun
{
int id_;
boost::function<...> f_;
public:
...
bool operator==(const EventFun& o) const { return id_==o.id_; } // you get it...
};
Note that this requires you maintain the id_ in a sane way (eg. two different EventFuns will have different id_s, etc.).
Another possibility would be to store boost::functions with a tag the client would remember and use to identify the particular function on deleting it.