You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用std::sort对指针指向的值排序?原尝试为何无效?

嘿,我来帮你搞清楚这个问题的来龙去脉,以及怎么解决它~

问题出在哪?

首先你得明白一个核心点:std::sort操作的是容器里的元素本身,而不是元素指向的内容。

你的初始代码里,容器存的是int*指针,sort做的只是把这些指针的地址在vector里重新排列——就像把几个指向不同盒子的标签重新排序,但盒子里的东西(原变量a、b、c的值)根本没碰,所以原变量自然不会变。

后来你尝试自定义assignement_pointer重载赋值运算符,但没用,是因为C++11之后std::sort优先使用移动语义(move)和swap操作来交换元素,而不是你重载的赋值运算符。你的包装类本质上还是在交换指针地址,原变量的值当然纹丝不动。

怎么实现“原变量跟着排序”?

你的需求本质是:排序指针的同时,让指针指向的原变量的值也变成有序的。这里有两种靠谱的思路:

思路1:直接排序值,写回原变量(简单直接)

如果不需要纠结“通过指针向量排序”这个形式,最省事的办法就是先把原变量的值取出来排序,再写回去,最后更新指针向量:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    int a = 3;
    int b = 2;
    int c = 1;

    // 1. 收集所有值并排序
    std::vector<int> sorted_values{a, b, c};
    std::sort(sorted_values.begin(), sorted_values.end());

    // 2. 把排序后的值写回原变量
    a = sorted_values[0];
    b = sorted_values[1];
    c = sorted_values[2];

    // 3. 更新指针向量(或者重新创建)
    std::vector<int*> vec{&a, &b, &c};

    std::cout << "vec = " << *vec[0] << ", " << *vec[1] << ", " << *vec[2] << '\n';
    std::cout << "abc = " << a << ", " << b << ", " << c << '\n';
}

运行后原变量和指针指向的内容都会是有序的。

思路2:自定义指针包装类,让swap交换值而非指针

如果你一定要通过指针向量的排序过程来触发原变量的交换,可以自定义一个包装类,重载swap操作——因为std::sort在交换元素时会调用swap,我们让它交换指针指向的原变量值,而不是指针本身:

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>

class ValueSwapPtr {
private:
    int* ptr;
public:
    explicit ValueSwapPtr(int* p) : ptr(p) {}

    // 重载解引用,方便获取值
    int& operator*() const { return *ptr; }
    int* get() const { return ptr; }

    // 核心:自定义swap,交换指向的原变量值
    friend void swap(ValueSwapPtr& lhs, ValueSwapPtr& rhs) {
        std::swap(*lhs.ptr, *rhs.ptr);
    }

    // 移动构造/赋值和拷贝赋值,都通过swap实现
    ValueSwapPtr(ValueSwapPtr&& other) noexcept : ptr(nullptr) {
        swap(*this, other);
    }

    ValueSwapPtr& operator=(ValueSwapPtr other) {
        swap(*this, other);
        return *this;
    }
};

// 排序用的比较函数,基于指向的值
bool compare(const ValueSwapPtr& a, const ValueSwapPtr& b) {
    return *a < *b;
}

int main() {
    int a = 3;
    int b = 2;
    int c = 1;

    std::vector<ValueSwapPtr> vec{&a, &b, &c};
    std::sort(vec.begin(), vec.end(), compare);

    std::cout << "vec = " << *vec[0] << ", " << *vec[1] << ", " << *vec[2] << '\n';
    std::cout << "abc = " << a << ", " << b << ", " << c << '\n';
}

这个代码运行后,原变量a、b、c的值会被交换成1、2、3,vector里的包装类指向的内容也会是有序的——因为sort每次交换元素时,都会触发我们自定义的swap,交换原变量的值。

最后总结
  • 原生指针排序只会动指针地址,碰不到原变量,这是std::sort的设计逻辑——它只操作容器内的元素。
  • 之前的包装类失效是因为sort用了move/swap而非赋值运算符,没触发你写的逻辑。
  • 两种解决方案选哪个看你的需求:追求简单就用思路1,一定要通过指针排序触发交换就用思路2。

内容的提问来源于stack exchange,提问作者Stack Danny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:11:51