我正在考虑使用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。
答案 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")