`

函数对象和模版,迭代器的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),需要采用归并排序)

分享到:
评论

相关推荐

    STL简单迭代器的实现

    迭代器有五种类型:输入迭代器(Input Iterator)、输出迭代器(Output Iterator)、前向迭代器(Forward Iterator)、双向迭代器(Bidirectional Iterator)和随机访问迭代器(Random Access Iterator),它们各自...

    STL中自定义排序的使用

    这里的`RandomAccessIterator`通常是容器(如`std::vector`、`std::list`等)的迭代器,`Compare`是一个比较函数对象或比较函数指针,用于定义排序规则。 1. **默认排序**:如果没有提供自定义的比较函数,`std::...

    std.rar

    `std`包含了大量预先定义的函数、类和对象,这些元素极大地丰富了C++的功能,使得开发者可以高效地处理输入/输出、数据结构、算法以及各种常用操作。 1. **输入/输出(I/O)**:`std::cin`和`std::cout`是C++中最...

    c++STL学习——排序算法技术总结和用法代码实例(二)

    此外,可能还会涉及到对链表(`std::list`)或其他非随机访问迭代器容器的排序。由于这些容器不支持随机访问,因此`std::sort`效率较低,此时可能需要使用`std::list`特有的`sort`成员函数。 总之,C++STL中的排序...

    STL学习代码

    `std::sort`接受三个参数:迭代器指向范围的开始,迭代器指向范围的结束,以及一个可选的比较函数对象,用于决定元素的排序顺序。在处理字符串时,通常按照字典顺序进行排序。`std::copy`函数则用于将一个范围内的...

    C++学习利器API大全(含函数说明及示例)

    3. **迭代器**:迭代器是访问容器元素的关键工具,如`std::begin()` 和 `std::end()` 用于获取容器的首尾迭代器。例如: ```cpp for(auto it = vec.begin(); it != vec.end(); ++it) { std::cout *it ; } ``` ...

    c++常用库函数速查手册(中文)

    2. **容器**:如`std::vector`、`std::array`、`std::list`、`std::map`、`std::set`等,这些容器提供了动态存储和操作数据的能力,支持迭代器和算法。 3. **迭代器**:如`begin()`、`end()`,它们是访问容器内元素...

    effectivec++

    - STL(Standard Template Library):熟悉STL的四大组件——容器、迭代器、算法和函数对象,以及如何有效利用它们。 8. **命名空间和作用域**: - 避免全局作用域污染:理解如何使用命名空间来组织代码,避免...

    C++使用sort函数进行容器排序.docx

    `sort`函数是C++标准模板库(STL)中的一个强大工具,它主要用于对容器中的元素进行排序。`sort`函数的实现基于快速排序算法,具有较高的效率。在实际应用中,我们常常需要对不同类型的数据进行排序,这不仅包括基本...

    c++ 标准库 STD

    3. **迭代器**:用于遍历容器中的元素,提供了访问容器内数据的一致性接口。 4. **输入/输出流**:如`iostream`、`fstream`等,支持基本的文本和二进制数据读写操作。 5. **字符串处理**:如`string`类,提供了...

    C++模板&STL.rarC++模板&STL.rar

    模板是C++中的泛型编程工具,而STL则是一系列高效算法、容器、迭代器和函数对象的集合,它们共同构建了C++的现代编程范式。 ### C++模板 1. **函数模板**:允许创建可以处理多种数据类型的函数。例如,通用的`swap...

    C++算法之通用排序

    C++ Standard Template Library (STL) 提供了一个名为`std::sort`的函数,它可以对任何随机访问迭代器范围内的元素进行排序。`std::sort`的原型如下: ```cpp template, class Compare &gt; void sort( RandomIt ...

    Effective C++跟more Effective c++

    - **迭代器**:理解和使用迭代器遍历容器,以及迭代器失效的问题。 - **算法**:掌握std::sort、std::find、std::transform等标准库算法,提升代码效率。 - **智能指针和unique_ptr**:使用智能指针管理动态分配...

    容器类的举例

    本节我们将通过实例深入探讨容器类的概念、使用以及与函数模板、类模板和引用的关系。 首先,我们要理解容器类的基本概念。容器类是一种对象,它定义了一种数据结构,并提供了操作这些数据的方法。例如,`std::...

    STL模板作业

    在编程领域,STL(Standard Template Library,标准模板库)是C++中极其重要的一个部分,它提供了一系列高效且功能强大的容器(如vector、list、set等)、算法(如排序、搜索、迭代器操作等)和迭代器。在这个“STL...

    c++学习笔记w版.pdf

    迭代器是C++标准库容器的核心工具,如`list&lt;T&gt;::const_iterator`和`list&lt;T&gt;::iterator`分别用于只读和读写操作。`begin()`和`end()`函数提供容器元素的访问起点和终点。例如,遍历`list`可以用`for (LI i = book....

    STL 1.算法之1.1Sort用法 及注意事项

    `sort`函数是C++ `&lt;algorithm&gt;`头文件中的一个通用排序算法,它接受三个参数:排序范围的起始迭代器、结束迭代器和一个可选的比较函数对象。对于基本类型如整型或浮点型,`sort`默认按照升序进行排序。例如,对一个...

    STL标准模板库

    在上述示例中,我们使用了`std::find`算法,该算法需要两个参数:迭代器范围的开始和结束,以及要查找的值。迭代器为算法提供了访问容器元素的方式,使得算法可以独立于容器类型而存在。 - **迭代器类型**: - **...

    C++编程惯用法——高级程序员常用方法和技巧

    - 利用拷贝构造函数和赋值运算符处理对象的复制行为,防止浅拷贝导致的问题。 - 实现移动构造函数和移动赋值运算符以优化资源转移,特别是在处理大对象时。 2. **内存管理**: - 使用智能指针(如`std::unique_...

    c++学习笔记w版.docx

    C++中的类和对象是面向对象编程的基础,它们有助于将复杂的程序结构组织成一组相互协作的概念。通过封装、继承和多态等机制,可以创建出更加灵活和可维护的代码。特别是,`virtual`关键字用于实现多态性,例如在声明...

Global site tag (gtag.js) - Google Analytics