提升lambda:在对象上调用方法

时间:2010-05-01 19:33:36

标签: c++ boost boost-lambda

我正在考虑使用boost :: lambda来制作一个可以使用任何类的任何“getter”方法的通用算法。

该算法用于检测属性的重复值,我希望它适用于任何类的任何属性。

在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());

我可以使用接口或模板方法让“任何类”部分工作,但还没有找到如何使“for any method”部分工作。

有没有办法在C ++中使用类似于“d =&gt; d.GetId()”lambda(有或没有Boost)?

替代方案,更多C ++ ian解决方案也可以使算法通用。

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

2 个答案:

答案 0 :(得分: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就像一个迭代器?),所以你可以填写英寸

答案 1 :(得分: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")