2012-06-04 73 views
1

我遇到的問題是我想在模板類中使用STL的自定義比較函數進行排序。對模板類中的成員函數使用`std :: sort`

使用的typedef的想法從另一個Stackoverflow Post

反正來了,這裏是代碼:

template <typename R,typename S> 
class mesh{ 
    /* some stuff */ 

    void sortData(){ 
    typedef bool (*comparer_t)(const S,const S); 
    comparer_t cmp = &mesh::compareEdgesFromIndex; 
    sort(indx,indx+sides*eSize,cmp); 
    } 

    /* more stuff */ 

    // eData and cIndx are member variables 
    bool compareEdgesFromIndex(const S a,const S b){ 
    return compareEdges(eData[cIndx[2*a]],eData[cIndx[2*a+1]],eData[cIndx[2*b]],eData[cIndx[2*b+1]]); 
    } 
}; 

我得到的錯誤是

mesh.h:130:29: error: cannot convert ‘bool (mesh<float, unsigned int>::*)(unsigned int, unsigned int)’ to ‘comparer_t {aka\ 
bool (*)(unsigned int, unsigned int)}’ in initialization 

預先感謝您!

回答

5

您正在嘗試混合使用成員函數指針,其中函數指針是必需的。您可以將謂詞重構爲static函數,或使用綁定將您的成員函數指針與類mesh的實例相關聯。

爲了一個實例綁定到你的成員函數指針如果與C++ 11工作你會做

std::bind(mesh_instance, &mesh::compareEdgesFromIndex, _1, _2) 

。如果您沒有奢侈品,那麼您可以使用Boost(替換std::bindboost::bind)的等效功能。 C++ 03提供了一些綁定功能,但它是有限的,我相信已過時現在通用綁定功能可用。

+0

對不起,作爲一個新手,第二個選項將如何實施? 謝謝! – Yuuta

+0

@Yuuta:查看更新的答案。 –

+0

非常感謝! – Yuuta

3

您必須聲明compareEdgesFromIndex爲靜態:

static bool compareEdgesFromIndex(const S a,const S b){ 
    return compareEdges(eData[cIndx[2*a]],eData[cIndx[2*a+1]],eData[cIndx[2*b]],eData[cIndx[2*b+1]]); 
} 

假設compareEdges也是靜態的。否則,你有一個成員函數指針,它需要調用一個mesh指針。

+0

謝謝你的回覆! 當聲明兩者都是靜態的,我得到一個錯誤,說eData和cIndx的使用是無效的 – Yuuta

+0

你應該閱讀什麼是靜態成員函數。你顯然必須修改你的代碼,所以它不依賴於實例變量,因爲你的方法是靜態的(這意味着它是某種「全局函數」)。我的答案只是修復你的錯誤信息:D。 – mfontanini

+0

謝謝你的澄清 – Yuuta

1

成員函數不是函數,因爲它的工作還需要知道哪個對象實例正在執行。 A static成員基本上只是一個常規的全局函數,具有一個有趣的名稱和訪問該類的私有部分的權限。

事實上,一個指向非靜態成員函數的指針並不是你可以簡單調用的東西,而是你可以提供一個對象實例來獲取你可以調用的東西的東西。

你能傳遞std::sort一個對象實例實現給定兩個指數將返回所需結果的::operator()(int, int)類的。不幸的是,由於我從來沒有在C++中理解的原因,這個對象類必須是非本地類,因爲本地類不能在模板中使用(它可以是在另一個類中定義的類,但不是在函數或方法中定義的類)。

+0

謝謝你的解釋! – Yuuta

3

或者,如果您希望使用compareEdgesFromIndex作爲非靜態成員函數,則可以將boost::bind(this, &mesh::compareEdgesFromIndex, _1, _2)作爲比較器。

+0

我沒有增強庫,但我會嘗試。 謝謝你的回覆! – Yuuta

+0

不客氣。您可以在boost.org上找到boost庫。它是跨平臺的,預構建包可用於各種操作系統。 – Greg

0

作爲std::bind的替代方法,您可以使用lambda,我更喜歡它,因爲我永遠不會記住std::bind的語法。

auto cmp = [&mesh_instance](unsigned lhs, unsigned rhs) { 
    return mesh_instance.compareEdgesFromIndex(lhs, rhs); 
};