我有一个像元组的向量
vector<tuple<T1, T2, T3>> v;
Run Code Online (Sandbox Code Playgroud)
我相信当默认比较为元组类型启动时,它会执行字典比较.
我可以按照我选择的元素进行比较吗?例如,通过上面例子中的第二个元素或者包含m个类型的元组中的第i个元素?
先感谢您.
Nik*_*iou 20
有很多方法可以做到这一点,我使用的方法归结为声明自定义比较对象,实际上如下
// Functor to compare by the Mth element
template<int M, template<typename> class F = std::less>
struct TupleCompare
{
template<typename T>
bool operator()(T const &t1, T const &t2)
{
return F<typename tuple_element<M, T>::type>()(std::get<M>(t1), std::get<M>(t2));
}
};
Run Code Online (Sandbox Code Playgroud)
它适用于任意长度的元组 (避免使用可变参数模板 - 即使以可变方式执行它相当容易和安全,因为您可以将operator()的参数声明为任意长度的元组)并且也适用于对,并且您可以通过它是一个自定义比较函数/对象,但使用<
运算符作为默认策略.一个示例用法是
int main()
{
vector<tuple<int, string>> v;
v.push_back(make_tuple(1, "Hello"));
v.push_back(make_tuple(2, "Aha"));
std::sort(begin(v), end(v), TupleCompare<0>());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有一种更现代的方式,通过使用lambdas,所以排序线将是
std::sort(begin(v), end(v),
[](tuple<int, string> const &t1, tuple<int, string> const &t2) {
return get<0>(t1) < get<0>(t2); // or use a custom compare function
}
);
Run Code Online (Sandbox Code Playgroud)
我相信值得为此创建一个函数对象(避免大量的样板代码)并采用第一种方法
由于Yakk的评论(在c ++ 1y上)符合标准(c ++ 14),我们在下面展示了通用lambda的情况
std::sort(begin(v), end(v), [](auto const &t1, auto const &t2) {
return get<0>(t1) < get<0>(t2); // or use a custom compare function
});
Run Code Online (Sandbox Code Playgroud)
这极大地匹配的力学TupleCompare
由于operator()
是模板也是如此.
Jen*_*unk 10
你可以这样做
#include <tuple>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
vector<tuple<int, float, char>> v;
int main() {
v.push_back(std::make_tuple(1,1.2,'c'));
v.push_back(std::make_tuple(1,1.9,'e'));
v.push_back(std::make_tuple(1,1.7,'d'));
sort(v.begin(),v.end(),
[](const tuple<int,float,char>& a,
const tuple<int,float,char>& b) -> bool
{
return std::get<1>(a) > std::get<1>(b);
});
cout << std::get<2>(v[0]) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是的,您可以在需要时在 C++ 中定义自定义排序。我想你需要它std::sort
,对吧?std::sort
准确地说,请查看算法的第二个版本的文档,即采用comp
参数的版本。
您必须定义一个小于函子,如下所示:
struct CustomLessThan
{
bool operator()(tuple<T1, T2, T3> const &lhs, tuple<T1, T2, T3> const &rhs) const
{
return std::get<1>(lhs) < std::get<1>(rhs);
}
};
Run Code Online (Sandbox Code Playgroud)
然后将其用于std::sort
:
std::sort(v.begin(), v.end(), CustomLessThan());
Run Code Online (Sandbox Code Playgroud)
在 C++11 中,您可以通过使用lambda而不是创建命名结构来缩短代码。cppreference.com 上给出的示例也展示了这种技术。