首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >根据pair.first对std::pair<int,std::unique_ptr<const T> >的向量进行排序

根据pair.first对std::pair<int,std::unique_ptr<const T> >的向量进行排序
EN

Stack Overflow用户
提问于 2018-07-25 01:16:43
回答 2查看 258关注 0票数 3

我正在尝试对包含const对象的智能指针的对的向量进行排序。我尝试仅根据第一个对象进行排序。下面你可以看到(我无数次尝试编写的代码之一)应该能做到这一点的代码,以及错误的摘录。

编译器会抱怨lambda参数。我已经尝试使用常量、非常量、引用、rvalue-reference参数,但都无济于事。帮帮忙好吗?

代码语言:javascript
复制
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;});

错误消息对我没有帮助:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-25 01:43:06

这里的问题是std::make_move_iterator的使用。当您这样做时,您将迭代器转换为move_iterator,这意味着当您取消对它们的引用时,您将获得一个T&&,而不是像使用普通迭代器那样的T&

在您的std::sort实现中使用的std::swap只接受左值引用,因此不能绑定到取消引用的迭代器。如果您使用

代码语言:javascript
复制
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将用于仅移动类型

票数 7
EN

Stack Overflow用户

发布于 2018-07-25 05:08:57

我对@NathanOliver的回答添加了一些进一步的解释,这对于评论来说太长了。我猜特工的想法是用

代码语言:javascript
复制
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::copystd::copy_ifstd::make_move_iterator的使用可能非常有用。它们通常使用像*output_it = *input_it这样的结构,再加上std::make_move_iterator,这对应于*output_it = std::move(*input_it),所以可以使用*output_it解除引用的类型的移动赋值运算符。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51504270

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档