我知道如果我有一个vector<int>
我可以像这样运行算法:
int max = *max_element(myints.begin(), myints.end());
但是,如果我有一个vector<MyStruct>
,其中struct中的一个字段是int。有没有一种优雅的方法可以在我的所有结构中的int中运行算法?
答案 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在不同的地方(或者如果我不得不使用凤凰城,但这是 只是个人的事情。)
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));