是否可以以优雅的方式在vector <mytype>上运行标准算法?</mytype>

时间:2011-09-26 14:29:46

标签: c++ c++11 std

我知道如果我有一个vector<int>我可以像这样运行算法:

int max = *max_element(myints.begin(), myints.end());

但是,如果我有一个vector<MyStruct>,其中struct中的一个字段是int。有没有一种优雅的方法可以在我的所有结构中的int中运行算法?

5 个答案:

答案 0 :(得分:11)

为max_element提供比较器:

MyStruct max = *max_element(v.begin(), v.end(),
    [](const MyStruct & lhs, const MyStruct & rhs) { return lhs.theInt < rhs.theInt; });

如果您的编译器还不支持lambdas,则必须编写单独的函数或函数对象类。

或者,如果您为您的班级重载operator<进行同样的比较,那么您可以这样做:

MyStruct max = *max_element(v.begin(), v.end());

答案 1 :(得分:4)

这取决于你对“优雅”的定义,但是,这可以做到。事实上,有许多不同的方式。

在标准C ++中,您可以使用Functor:

#include <algorithm>
#include <vector>
#include <functional>
using namespace std;

class Gizmo
{
public:
    int n_;
};

class BiggestGizmo : public std::binary_function<bool, Gizmo, Gizmo>
{
public:
    bool operator()(const Gizmo& lhs, const Gizmo& rhs) const
    {
        return lhs.n_ > rhs.n_;
    }
};

int main()
{
    typedef vector<Gizmo> Gizmos;
    Gizmos gizmos;
    Gizmos::const_iterator it = max_element(gizmos.begin(), gizmos.end(), BiggestGizmo());
}

在C ++ 0X中,您可以使用Lambda:

#include <algorithm>
#include <vector>
using namespace std;

class Gizmo
{
public:
    int n_;
};

int main()
{
    typedef vector<Gizmo> Gizmos;
    Gizmos gizmos;
    Gizmos::const_iterator it = max_element(gizmos.begin(), gizmos.end(), [](const Gizmo& lhs, const Gizmo& rhs) -> bool
    {
        return lhs.n_ > rhs.n_;
    });
}

答案 2 :(得分:2)

混合中的另一个选项:您可以编写自己的迭代器类,其引用和值类型为int&int,但它们位于迭代器之上,引用类型为{{1提供对该字段的访问权。

除了向MyStruct&提供额外的比较器之外,还有一些工作要做,但是如果你做了一次,那么你已经为所有算法完成了它,而不仅仅是通过比较器行事。如果您可以使用它,max_element将为您处理样板。

boost::transform_iterator不允许你从实例中获取底层迭代器,但是在boost::transform_iterator的情况下由于它是随机访问而无关紧要,因此它的计算效率很高距离并将其应用于vector迭代器。

答案 3 :(得分:1)

对于结构,您可以定义比较函数或对象。您还可以为结构定义<运算符。这是一个example

答案 4 :(得分:0)

正如您在其中一条评论中所说,您有许多班级成员,并希望在算法中单独解决每个问题。你最终会有各种可能性

  • 到处都是lambdas(凤凰城或C ++ 11)
  • 每个案例的仿函数
  • 每个案例的成员函数

如果我需要重复这个,我更喜欢最后两个解决方案 lambdas在不同的地方(或者如果我不得不使用凤凰城,但这是 只是个人的事情。)

struct Foo {
  int a;
  int b;
  bool less_than_by_a(const Foo&) const;
  bool less_than_by_b(const Foo&) const;
};

std::max_element(begin, end, std::mem_fun_ref(&Foo::less_than_by_a));
std::max_element(begin, end, std::mem_fun_ref(&Foo::less_than_by_b));