2012-09-18 141 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(),除非有一些繼承涉及或什麼)。您可能需要發佈比這更多的代碼(特別是類定義)。