2010-05-01 94 views
0

我正在尋找boost :: lambda作爲一種通用算法,可以與任何類的任何「getter」方法一起使用。Boost lambda:對象的調用方法

該算法用於檢測屬性的重複值,我希望它適用於任何類的任何屬性。

在C#中,我會做這樣的事情:

class Dummy 
{ 
    public String GetId() ... 
    public String GetName() ... 
} 

IEnumerable<String> FindNonUniqueValues<ClassT> 
    (Func<ClassT,String> propertyGetter) { ... } 

例使用的方法:

var duplicateIds = FindNonUniqueValues<Dummy>(d => d.GetId()); 
var duplicateNames = FindNonUniqueValues<Dummy>(d => d.GetName()); 

我可以得到的「任何類」部分的工作,即使用接口或模板方法,但尚未找到如何使「用於任何方法」的部分工作。

有沒有辦法在C++中使用類似於「d => d.GetId()」lambda的方法(使用或不使用Boost)?

另外,更多的C++ ian解決方案使算法具有通用性也是值得歡迎的。

我使用VS2008的C++/CLI,所以我不能使用C++ 0x lambdas。

+1

如果它適合你,一個*「多C++伊恩解決方案」 *會去用的''職能的風格,例如見'獨特()'/'unique_copy()'。 – 2010-05-01 20:16:50

+0

我的理解是,如果我有一個向量,並且想要在向量中找到非唯一的T,而不是在尋找非唯一的T.method( ) – ckarras 2010-05-01 20:31:40

+0

像unique()這樣的許多算法調用都有第二種形式允許傳遞謂詞,而不是使用默認操作 - 例如'unique(myVec.begin(),myVec.end(),myComparator())'。 – 2010-05-01 23:40:47

回答

6

假設,我知道你在找什麼,你可以使用boost::bind

FindNonUniqueValues<Dummy>(boost::bind(&Dummy::GetId, _1)); 

其實,你只需要boost::mem_fn甚至std::mem_fun,但boost::bind可以讓你多一點共性。

在這種情況下,您將定義FindNonUniqueValues,就像這樣:

template <typename T> 
/* ? */ FindNonUniqueValues(boost::function<std::string (const T&)> getter) { ... } 

在這裏,我真的不知道你的FindNonUniqueValues如何得到它的對象的列表(或正是它應該返回 - 是的?IEnumerable像一個迭代器),所以你可以填補在

+0

@gf,當然,爲什麼不呢? (編輯) – 2010-05-01 19:53:56

+0

謝謝,我試了boost :: bind和std :: mem_fun。這兩個解決方案都可以工作,但我發現std :: mem_fun更符合我的需求。 – ckarras 2010-05-01 20:29:50

2

以供將來參考,這裏是我結束瞭解決方案,從公認的答案如下想法後:

template < typename ObjectT, typename ValueT > std::vector <ObjectT> 
FindInstancesWithDuplicateValue(
    vector<ObjectT> allValues, mem_fun_ref_t<ValueT, ObjectT> getter) 
{ 
    // [...create a *sorted* list of ObjectT, ordered by ObjectT.getter()...] 
    // [...loop through the sorted list to find identical adjacent values...] 
     // call the mem_fun_ref_t: 
     ValueT value1 = getter(*iterPrev); 
     ValueT value2 = getter(*iter); 
     if (value1 == value2) // duplicates found 
    // ... 
} 

使用例:

vector<Dummy> list; 
list.push_back(Dummy(1, "1-UniqueValue")); 
list.push_back(Dummy(2, "2-DuplicateValue")); 
list.push_back(Dummy(3, "2-DuplicateValue")); 
list.push_back(Dummy(4, "3-UniqueValue")); 

vector<Dummy> dummyWithduplicateNames = 
    FindInstancesWithDuplicateValue<Dummy,CString> 
    (list, mem_fun_ref(&Dummy::GetName)); 

// returns Dummy(2, "2-DuplicateValue") and Dummy(3, "2-DuplicateValue")