对 std::pair<int, std::unique_ptr<const T> 的向量进行排序 > 取决于 pair.first
sorting a vector of std::pair<int, std::unique_ptr<const T> > depending on pair.first
我正在尝试对包含 const 对象的智能指针的对向量进行排序。我试图仅根据第一个对象进行排序。下面你会看到(我多次尝试编写的代码之一)应该执行此操作的代码,以及错误的摘录。
编译器抱怨 lambda 参数。我试过使参数为常量、非常量、引用、右值引用,但都无济于事。请帮忙?
std::pair<int, std::unique_ptr<const std::string> > a;
auto uniq = std::make_unique<const std::string>("hurz");
a = std::make_pair(1,std::move(uniq));
std::pair<int, std::unique_ptr<const std::string> > b;
uniq = std::make_unique<const std::string>("hurz");
b = std::make_pair(2,std::move(uniq));
std::vector<std::pair<int,std::unique_ptr<const std::string> > > vec;
vec.push_back(std::move(a));
vec.push_back(std::move(b));
std::sort(std::make_move_iterator(vec.begin()),
std::make_move_iterator(vec.end()),
[]
(const std::pair<int,std::unique_ptr<const std::string> >& i1,
const std::pair<int,std::unique_ptr<const std::string> >& i2)
{ return i1.first > i2.first;});
错误消息对我没有帮助:
error: no matching function for call to
'swap(std::move_iterator<__gnu_cxx::__normal_iterator<std::pair<int,
std::unique_ptr<const std::basic_string<char> > >*, std::vector<std::pair<int,
std::unique_ptr<const std::basic_string<char> > > > > >::value_type,
std::move_iterator<__gnu_cxx::__normal_iterator<std::pair<int,
std::unique_ptr<const std::basic_string<char> > >*, std::vector<std::pair<int,
std::unique_ptr<const std::basic_string<char> > > > > >::value_type)' swap(*__a,
*__b);
candidates are:
/usr/include/c++/4.9/bits/move.h:166:5: note: void std::swap(_Tp&, _Tp&)
[with _Tp = std::pair<int, std::unique_ptr<const std::basic_string<char> > >]
plus many more errors in the same vein
这里的问题是 std::make_move_iterator
的使用。当你这样做时,你将迭代器变成 move_iterator
,这意味着当你取消引用它们时,你会得到一个 T&&
,而不是像你对普通迭代器所做的那样 T&
。
std::swap
,它在您的 std::sort
实现中使用,只接受左值引用,因此它不能绑定到取消引用的迭代器。如果你使用
std::sort(vec.begin(),
vec.end(),
[]
(const std::pair<int,std::unique_ptr<const std::string> >& i1,
const std::pair<int,std::unique_ptr<const std::string> >& i2)
{ return i1.first > i2.first;});
相反,您将拥有 std::swap
的左值来绑定并且 std::swap
将适用于仅移动类型
我对@NathanOliver 的回答添加了一些进一步的解释,这太长了,无法发表评论。我猜 OP 的想法是使用
std::sort(std::make_move_iterator(vec.begin()), std::make_move_iterator(vec.end()),
[](const std::pair<int,std::unique_ptr<const std::string> >& i1,
const std::pair<int,std::unique_ptr<const std::string> >& i2)
{ return i1.first > i2.first;});
即,将 move_iterator
应用于 vector.begin()
,是在排序例程中使用移动分配(而不是复制)。这个想法很诱人,但没有必要,因为在 std::sort
中,赋值通常用 std::swap
和 tries to move arguments passed by reference 完成。
另一方面,对于使用输入和输出迭代器的算法,例如最基本的 std::copy
或 std::copy_if
,使用 std::make_move_iterator
可能非常有用。那些经常使用像 *output_it = *input_it
这样的构造,并且与 std::make_move_iterator
一起对应于 *output_it = std::move(*input_it)
,因此可以使用 *output_it
取消引用类型的移动赋值运算符。
我正在尝试对包含 const 对象的智能指针的对向量进行排序。我试图仅根据第一个对象进行排序。下面你会看到(我多次尝试编写的代码之一)应该执行此操作的代码,以及错误的摘录。
编译器抱怨 lambda 参数。我试过使参数为常量、非常量、引用、右值引用,但都无济于事。请帮忙?
std::pair<int, std::unique_ptr<const std::string> > a;
auto uniq = std::make_unique<const std::string>("hurz");
a = std::make_pair(1,std::move(uniq));
std::pair<int, std::unique_ptr<const std::string> > b;
uniq = std::make_unique<const std::string>("hurz");
b = std::make_pair(2,std::move(uniq));
std::vector<std::pair<int,std::unique_ptr<const std::string> > > vec;
vec.push_back(std::move(a));
vec.push_back(std::move(b));
std::sort(std::make_move_iterator(vec.begin()),
std::make_move_iterator(vec.end()),
[]
(const std::pair<int,std::unique_ptr<const std::string> >& i1,
const std::pair<int,std::unique_ptr<const std::string> >& i2)
{ return i1.first > i2.first;});
错误消息对我没有帮助:
error: no matching function for call to
'swap(std::move_iterator<__gnu_cxx::__normal_iterator<std::pair<int,
std::unique_ptr<const std::basic_string<char> > >*, std::vector<std::pair<int,
std::unique_ptr<const std::basic_string<char> > > > > >::value_type,
std::move_iterator<__gnu_cxx::__normal_iterator<std::pair<int,
std::unique_ptr<const std::basic_string<char> > >*, std::vector<std::pair<int,
std::unique_ptr<const std::basic_string<char> > > > > >::value_type)' swap(*__a,
*__b);
candidates are:
/usr/include/c++/4.9/bits/move.h:166:5: note: void std::swap(_Tp&, _Tp&)
[with _Tp = std::pair<int, std::unique_ptr<const std::basic_string<char> > >]
plus many more errors in the same vein
这里的问题是 std::make_move_iterator
的使用。当你这样做时,你将迭代器变成 move_iterator
,这意味着当你取消引用它们时,你会得到一个 T&&
,而不是像你对普通迭代器所做的那样 T&
。
std::swap
,它在您的 std::sort
实现中使用,只接受左值引用,因此它不能绑定到取消引用的迭代器。如果你使用
std::sort(vec.begin(),
vec.end(),
[]
(const std::pair<int,std::unique_ptr<const std::string> >& i1,
const std::pair<int,std::unique_ptr<const std::string> >& i2)
{ return i1.first > i2.first;});
相反,您将拥有 std::swap
的左值来绑定并且 std::swap
将适用于仅移动类型
我对@NathanOliver 的回答添加了一些进一步的解释,这太长了,无法发表评论。我猜 OP 的想法是使用
std::sort(std::make_move_iterator(vec.begin()), std::make_move_iterator(vec.end()),
[](const std::pair<int,std::unique_ptr<const std::string> >& i1,
const std::pair<int,std::unique_ptr<const std::string> >& i2)
{ return i1.first > i2.first;});
即,将 move_iterator
应用于 vector.begin()
,是在排序例程中使用移动分配(而不是复制)。这个想法很诱人,但没有必要,因为在 std::sort
中,赋值通常用 std::swap
和 tries to move arguments passed by reference 完成。
另一方面,对于使用输入和输出迭代器的算法,例如最基本的 std::copy
或 std::copy_if
,使用 std::make_move_iterator
可能非常有用。那些经常使用像 *output_it = *input_it
这样的构造,并且与 std::make_move_iterator
一起对应于 *output_it = std::move(*input_it)
,因此可以使用 *output_it
取消引用类型的移动赋值运算符。