Boost lambda:调用对象上的方法

发布于 2024-08-30 15:30:53 字数 757 浏览 8 评论 0原文

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

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

有没有办法做一些类似于 C++ 中的“d => d.GetId()”lambda 的事情(无论有没有 Boost)?

另外,更多使算法具有通用性的 C++ 解决方案也受到欢迎。

我在 VS2008 中使用 C++/CLI,因此无法使用 C++0x lambda。

I'm looking at boost::lambda as a way to to make a generic algorithm that can work with any "getter" method of any class.

The algorithm is used to detect duplicate values of a property, and I would like for it to work for any property of any class.

In C#, I would do something like this:

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

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

Example use of the method:

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

I can get the for "any class" part to work, using either interfaces or template methods, but have not found yet how to make the "for any method" part work.

Is there a way to do something similar to the "d => d.GetId()" lambda in C++ (either with or without Boost)?

Alternative, more C++ian solutions to make the algorithm generic are welcome too.

I'm using C++/CLI with VS2008, so I can't use C++0x lambdas.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

盗梦空间 2024-09-06 15:30:53

假设,我明白你在寻找什么,你可以使用 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 是像迭代器一样吗?),所以你可以填写它。

Assuming, I understand what you're looking for, you can use boost::bind:

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

Actually, you just need boost::mem_fn or even std::mem_fun, but boost::bind will allow you a bit more generality.

In this case, you would define FindNonUniqueValues as something like:

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

Here, I'm not really sure how your FindNonUniqueValues gets its list of objects (or exactly what it's supposed to return - is an IEnumerable like an iterator?), so you could fill that in.

帅的被狗咬 2024-09-06 15:30:53

为了便于将来参考,这是我在遵循已接受答案的想法后得出的解决方案:

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")

For future reference, here's the solution I ended with, after following ideas from the accepted answer:

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
    // ...
}

Example use:

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")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文