函数对象和模版,迭代器的const 引用——std::sort遇到的问题

先声明,各个std库实现不一样,因此有必要按照标准的来。

经常需要对vector进行排序,但是vector常存放的是指针

 

 

template<class T>
        struct StatLess{
            bool operator()(const  T& first,const T& second)const{
                return first->value<second->value;
            }
        };

struct LinkStatRecord
{
int value;
};

int main(int argc,char*argv[])
{
        std::vector<LinkStatRecord*> vec;
        vec.reserve(5);
        std::sort(vec.begin(),vec.end(),StatLess<LinkStatRecord*>());
        return 0;
}

 这是个演示例子,vec是空的,但程序是可以正常编译运行的。

 

可以看到的上面的模版类似乎很多余,看起来T的类型就是 LinkState*,于是改成如下:

 

struct StatLess{
            bool operator()(const  LinkStatRecord* first,const LinkStatRecord* second)const{
                return first->value<second->value;
            }
        };

 

 

这个可以在VC(2005,2008,)编译器都可以,但是这个是错误的。gcc如下:

 

错误:对‘sort(__gnu_cxx::__normal_iterator<LinkStatRecord**, std::vector<LinkStatRecord*, std::allocator<LinkStatRecord*> > >, __gnu_cxx::__normal_iterator<LinkStatRecord**, std::vector<LinkStatRecord*, std::allocator<LinkStatRecord*> > >, StatLess)’的调用没有匹配的函数 

 

类似的,还有引用,一定要用const如下面的const&限定

 bool operator()(const  T& first,const T& second)const{
                return first->value<second->value;
            }

 

如果没有const限定,也是在VC编译器中可行,gcc错误。

 

顺便说下std::sort,它的第三个函数对象或者函数都是可以的,类似的,如果使用比较函数可以写成

bool compare(const  T& first,const T& second){
    return first->value<second->value;
}

同理,如果用引用,必须要使用const限定,当然最好也是用const引用方式。

不少书上说,函数对象可以内联,而函数方式不能内联(调用的时候传入的是指针),因此,建议用函数对象(Function Object);这个似乎站不住脚(没有去确认)。

 

sort是不稳定排序,如果需要稳定stable_sort,用法相同。但实现是不同的,stable_sort要复杂得多,算法复杂度也有区别(如果空间不够,N*log2(N)*log2(N),空间足够Nlog2(N),需要采用归并排序)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`std::sort`是C++标准库中的一个函数模板,主要用于对容器中的元素进行排序。然而,它不能直接用来排序`std::map`。原因在于`std::map`本身是一种基于键值对的容器,并且它默认按照键的顺序存储元素,也就是说`std::map`内部就是有序的。`std::map`的排序规则是基于其键的比较函数`std::less`,或者是用户定义的比较函数。 如果要使用`std::sort`来对`std::map`中的元素进行排序,你需要先将`std::map`中的元素复制到一个可以排序的容器中,比如`std::vector`,然后使用`std::sort`对这个容器进行排序。排序后,你可以将排序后的元素再复制回`std::map`(如果需要的话),但这样做通常没有太大的实际意义,因为`std::map`的有序特性在操作完成后可能会被破坏。 如果你想要在遍历`std::map`时按照特定的顺序输出元素,可以通过对`std::map`的迭代器进行排序来实现。例如,如果你想根据键的值进行升序排序,可以直接使用默认的`std::less`比较函数: ```cpp #include <iostream> #include <map> #include <vector> #include <algorithm> // for std::sort int main() { std::map<int, int> m = {{3, 1}, {1, 2}, {2, 3}}; // 将map的键值对复制到vector中 std::vector<std::pair<int, int>> v(m.begin(), m.end()); // 使用默认的比较函数std::less对vector进行排序 std::sort(v.begin(), v.end()); // 输出排序后的元素 for (const auto& p : v) { std::cout << p.first << ": " << p.second << std::endl; } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值