2014-09-25 14 views
5

Edytuję prosty przykład QDomModel, aby dodać trochę mięsa do mojej aplikacji i trzeba wyczyścić niektóre flagi stanu, które dodałem od czasu do czasu. Iterowanie przez elementy modelu QAbstractItem jest irytujące, ponieważ nie ma standardowego iteratora, więc napisałem własną funkcję for_each-style, aby iterować każdy element i wykonywać na nim funkcję "f".QAbstractItemModel foreach iterator z funktorami: czy jest lepszy sposób na zrobienie tego?

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); 
} 

To działa i mogę dać wszelkiego rodzaju wielkich lambdas lub funktorów i nazwać tak:

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

To jest bardzo silny, ale problem mam jest, że jeśli wkopany w kod, nie masz pojęcia, jaki powinien być podpis funktora/lambda. Otrzymujesz błąd kompilacji, jeśli coś źle, ale obawiam się, że może to być zły interfejs (lub ogólnie zła praktyka kodowania) do tworzenia tego typu funkcji.

Czy lepiej jest, gdy przyjmując argumenty, poprosić o wskaźniki funkcji dla jasności? Czy są jakieś implikacje lub ograniczenia dotyczące sposobu w jaki sposób powinienem być świadomy?

+0

Standardowa biblioteka po prostu dokumentuje oczekiwany podpis funkcji. Utworzenie 'std :: function', ponieważ używa funkcji wymazywania typów, zmniejsza wydajność w porównaniu do zwykłych funkcji lub lambdas. –

Odpowiedz

2

std::function pozwoli ci pokazać typ w podpisie. Wypróbuj coś takiego:

void foreach_item(const std::function<void(const QModelIndex&)> &f, QModelIndex parent = QModelIndex()) 
{ 
    /*...*/ 
}