2012-09-18 100 views
1

我有一个通用的函数,我正在使用List类中的某些对象进行排序。函数指针和继承

该函数工作得很好,但是当我想使用函数指针将该函数应用于类中的成员函数时,它不会生成。

的功能是:

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

其中列表是包含对象的列表类,FX是函数指针访问对象和爆击是用于排序的对象的比较函数。

当我建立使用这一行:

trie(vend,&Vendeurs::getVend,&Vendeur::getNom); 

我得到这个错误:

dialogfaitlisting.cpp:459: erreur : no matching function for call to 
'DialogFaitListing::trie(Vendeurs*&, Vendeur (Vendeurs::*)(quint16), 
QString (Personne::*)())' 

PS:对不起,我的英语不好

+2

你是[三星程序员](http://c2.com/cgi/wiki?ThreeStarProgrammer)?让事情变得简单! – Lol4t0

+0

您需要提供一个更简单,更完整的示例。例如,如果没有看到如何声明模板类,就不可能知道所有可能的错误。此外,在这里执行特里并不重要;它只会增加噪音。尝试将您的代码缩小到仍然产生错误的最小示例,并发布整个结果(可能在单个.cpp文件中有10行左右)。 – phord

回答

0

&Vendeur::getNom尽管是通过Vendeur访问的成员,但似乎有QString (Personne::*)()类型。这使得T2在模板论证扣除期间模棱两可:是Vendeur还是Personne

创可贴解决将是把负担的trie呼叫者明确将其转换为QString (Vendeur::*)(),导致下面的调用:

trie(vend, &Vendeurs::getVend, static_cast<QString (Vendeur::*)()>(&Vendeur::getNom)); 

这是非常繁琐和不便,考虑到我们每当我们想要传递的012.版本都来自基类时,我们可能会发现同样的错误。

更好的解决方法是在出现T2的两个点之一上禁止模板参数推演。我认为这将是有意义的选择第二点为:

template<typename T> 
struct identity { typedef T type; }; 

template <typename T1, typename T2, typename T3> 
void trie(T1 * list 
    , T2 (T1::*fx)(quint16) 
    , T3 (identity<T2>::type::*crit)()); 

然后在通话T2只能推断为Vendeur&Vendeur::getNom将被隐式转换为QString (Vendeur::*)()

0

看来,要同时试图限制T2Vendeur第二个参数为trie(因为Vendeur Vendeurs::getVend(quint16))和Personne在第三个参数(但我不知道它是如何从&Vendeur::getNomQstring Personne::function(),除非有一些继承涉及或什么)。您可能需要发布比这更多的代码(特别是类定义)。