2011-11-08 64 views
1

因此,我一直在努力想辦法解決某些問題。我想我會在這裏發佈,看看有沒有人有任何想法。考慮以下幾點:我想要一個模板函數,它需要一個指向成員的指針,但我不希望必須通過類類型和成員類型

template <typename S, typename T, T S::* pMember> 
bool SortByMember(const S& L, const S& R) 
{ 
    return L.*pMember < R.*pMember; 
} 

... 

struct SomeStruct 
{ 
    int SomeMember; 
}; 

void SomeFunction(void) 
{ 
    GetSortByMember<&SomeStruct::SomeMember>(); 
} 

我想功能,GetSortByMember,一個函數指針返回SortByMember對應的實例。但是,我想不出一種方式來聲明/定義GetSortByMember,而不需要用戶也傳遞類類型和成員類型。這個:

GetSortByMember<SomeStruct, int, &SomeStruct::SomeMember>(); 

過於冗長,需要我說明成員類型。我確信在boost庫中可能有一個解決方案,但我寧願不將該依賴項引入到我正在開發的項目中。

我非常懷疑有一種解決方案可以產生我在psudocode中使用的確切語法,但也許可以使用模板類或宏來完成某些工作?

SortByMember的簽名是由將使用函數指針的類預期的,所以它不能被更改。

+0

如果你使用宏,整個開發看起來很簡單,不是嗎? –

+0

沒有像「指向成員函數的指針」這樣的「指向成員的指針」。 –

+2

^這是不正確的,請參閱http://stackoverflow.com/questions/670734/c-pointer-to-class-data-member。 –

回答

0

有可能是你想要什麼更好的方式,但這個工程使用宏和GCC具體的typeof()。我不確定,但是可能有一種可移植的方式來在新的C++標準中進行typeof。

#include <iostream> 

template <class P, P p> 
class sort_by_member_t; 

template <class S, class T, T S::*p> 
class sort_by_member_t<T S::*, p> { 
public: 
    typedef bool (*fn_t)(S const&, S const&); 

    static bool fn(S const& L, S const& R) 
    { 
     return L.*p < R.*p; 
    } 
}; 

#define SORT_BY_MEMBER(p) sort_by_member_t<typeof(p), p>::fn; 

struct SomeStruct 
{ 
    int SomeMember; 
}; 


int main() 
{ 
    bool (*fp)(SomeStruct const&, SomeStruct const&); 
    fp = SORT_BY_MEMBER(&SomeStruct::SomeMember); 
    SomeStruct const a = { 1 }; 
    SomeStruct const b = { 2 }; 
    std::cerr 
     << (void*) fp << ' ' 
     << (*fp)(a, b) << ' ' 
     << (*fp)(b, a) << ' ' 
     << '\n'; 

    return 0; 
} 
+0

如果我找不到更好的解決方案,這可能會沿用我將使用的解決方案。我更喜歡我的代碼是可移植的,但我使用GCC,所以這將工作。我並沒有真正使用新的C++標準,但它確實提供了decltype關鍵字,它本質上是typeof的標準化版本。 –

+0

我會有興趣看到更好的方法,因爲我現在不得不做類似的事情。我認爲不可避免的問題是,只有在知道它的類型時,才能將值傳遞給模板。你可以從早期的類型參數中獲得它的類型,但是你必須傳遞兩個參數。您可以使用typeof/decltype獲取表達式的類型,但僅表達一次表達式的唯一方法是使用宏。我個人並不認爲宏是普遍邪惡的,他們應該是最後的武器。 –

0

你的例子不清楚,大概你需要用兩個參數調用結果函數?如果是這樣,爲什麼不使用一個getter函數,並通過在,e.g:

#include <iostream> 

struct foo 
{ 
    int bar; 
    int getBar() const { return bar; } 
}; 

template <typename S, typename U> 
bool SortByMember(const S& L, const S& R, U f) 
{ 
    return (L.*f)()< (R.*f)(); 
} 

int main(void) 
{ 
    foo a = {1}; 
    foo b = {2}; 

    std::cout << SortByMember(a, b, &foo::getBar) << std::endl; 
} 
+0

兩個原因。其一,我可能正在使用其他庫的類,也就是說,我不能爲它們添加'getBar'函數。二,這將是一個運行時解決方案,而我正在尋找一個編譯時解決方案。 此外,我實際上需要一個函數指針,因爲我將存儲該指針,然後再調用它。 –

+0

不相關,它將指針轉換爲最初引用數據類型的成員,作爲指向成員函數的指針。 –

+0

@ TheOrangeMan:你能否進一步解釋一下* compile *和* runtime *解決方案的意思,以及爲什麼你需要*前者? –

相關問題