I’ve got a generic function I’m using to sort some Objects in List class.
This function works very well but when I want to apply this function to a class using a function pointer to a member function in that class, it don’t build.
The function is:
template <typename T1, typename T2, typename T3>
void DialogFaitListing::trie(T1 * list, T2 (T1::*fx)(quint16), T3 (T2::*crit)())
{
for(int i(0);i<list->count();i++)
{
for(int j(i);j<list->count();j++)
{
if((((list->*fx)(i)).*crit)() > (((list->*fx)(j)).*crit)())
{
list->swap(i,j);
}
}
}
}
where list is the Class which contains the list of objects, fx is the function pointer to access the object and crit is the objects comparison function for the sort.
When I build using this line:
trie(vend,&Vendeurs::getVend,&Vendeur::getNom);
I get this error:
dialogfaitlisting.cpp:459: erreur : no matching function for call to
'DialogFaitListing::trie(Vendeurs*&, Vendeur (Vendeurs::*)(quint16),
QString (Personne::*)())'
ps: sorry for my bad English
&Vendeur::getNom, despite being a member accessible throughVendeur, appears to have typeQString (Personne::*)(). This makesT2ambiguous during template argument deduction: is itVendeuror is itPersonne?A band-aid fix would be to put the burden on the caller of
trieto explicitly convert it toQString (Vendeur::*)(), result in the following call:This is very verbose and inconvenient, considering that we’re likely to find the same error each time the
criterion we wish to pass comes from a base class.A better solution is to inhibit template argument deduction on one of the two spots where
T2appears. I think it would make sense to choose the second spot for that:Then in the call
T2can only be deduced to beVendeurand&Vendeur::getNomwill be implicitly converted toQString (Vendeur::*)().