Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QAbstractItemModel foreach iterator with functors: is there a better way to do this?

I'm editing the QDomModel simple example to add some meat for my application, and need to clear some state flags that I've added occasionally. Iterating through the items of a QAbstractItem model is sort of annoying since no standard iterator is provided, so I've written my own for_each-style function to iterate through each item and perform function 'f' on it.

template<typename Functor>
void foreach_item(Functor f, QModelIndex &parent = QModelIndex())
{
    if (!parent.isValid())
        parent = index(0,0,QModelIndex());

    int numRows = rowCount(parent);

    for (int i=0; i<numRows; i++)
    {
        foreach_item(f,index(i,0,parent));      
    }

    f(parent);  
}

This works and I can give it all kinds of great lambdas or functors and call it like so:

void QDomModel::clearChanges()
{
    foreach_item([&](QModelIndex parent)
    {   
        QDomItem* item = static_cast<QDomItem*>(parent.internalPointer());
        item->valueChanged = false;
    });
    changeCount = 0;
}

This is very powerful, but the problem I'm having is that unless you dug into the code, you'd have no idea what the signature of the functor/lambda is supposed to be. You do get a compile error if you give it something wrong, but I'm worried that this may be a bad interface (or a bad coding practice in general) for creating these types of functions.

Is it better, when taking in arguments, to ask for function pointers for clarity? Are there any implications or limitations to doing one way versus the other that I should be aware of?

like image 489
Nicolas Holthaus Avatar asked Nov 01 '22 16:11

Nicolas Holthaus


1 Answers

std::function will allow you to expose the type in the signature. Try something like:

void foreach_item(const std::function<void(const QModelIndex&)> &f, QModelIndex parent = QModelIndex())
{
    /*...*/
}
like image 200
jturcotte Avatar answered Nov 15 '22 07:11

jturcotte