是否可以以优雅的方式在向量上运行标准算法<MyType>?
Is it possible to run standard algorithms on vector<MyType> in an elegant way?
我知道如果我有一个vector<int>
,我可以在它上面运行这样的算法:
int max = *max_element(myints.begin(), myints.end());
但是如果我有一个vector<MyStruct>
,其中一个结构体中的字段是int,该怎么办?有没有一种优雅的方法可以在所有结构体中的整数上运行算法?
为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());
这取决于你对"优雅"的定义,但是,是的,这是可以做到的。事实上,在许多不同的方面。
在标准c++中,可以使用函子:
#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_;
});
}
另一种选择:您可以编写自己的迭代器类,其引用类型和值类型为int&
和int
,但它在引用类型为MyStruct&
的迭代器上运行,提供对该字段的访问。
这比仅仅为max_element
提供一个额外的比较器要多一点工作,但是如果你做了一次,那么你已经为所有的算法做了,而不仅仅是那些通过比较器起作用的算法。如果您可以使用它,boost::transform_iterator
将为您处理样板文件。
boost::transform_iterator
不允许您从实例中获得底层迭代器,但在vector
的情况下,这无关紧要,因为它是随机访问的,因此计算距离并将其应用于begin()
迭代器是有效的。
对于结构体,可以定义比较函数或比较对象。您还可以为您的结构定义<
操作符。下面是一个例子
正如您在其中一个评论中所说的,您有许多类成员,并且希望在算法中分别处理每个成员。你会得到各种各样的可能性
- lambdas无处不在(无论是Phoenix还是c++ 11)
- 每个case的函子
- 每个case的成员函数
只有当我需要重复时,我才会选择后两个解决方案lambda在不同的地方(或者如果我必须使用Phoenix,但这是这是个人的事情)。
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));
- 使用CMake检测支持的C++标准
- 如何理解C++标准N3337中的expr.const.cast子句8
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 呼叫运营商<<临时
- 编译标准库类型
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 铸造标准::有没有回到原来的类型
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 标准库类型的赋值运算符的引用限定符
- 标准是否严格定义了该程序应该如何编译?
- 如何从Windows应用程序输出到标准?
- 安全到标准:移动会员?
- 如何正确将字符串转换为标准::时间::system_clock::time_point?
- 这是否符合C++标准:双响双响,例如!!(-0.0).
- C++标准::cout和<<操作员,优先级