Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用std::sort()对指向值的向量进行排序?_C++_Sorting_C++11_Pointers - Fatal编程技术网

C++ 如何使用std::sort()对指向值的向量进行排序?

C++ 如何使用std::sort()对指向值的向量进行排序?,c++,sorting,c++11,pointers,C++,Sorting,C++11,Pointers,已经有帖子了,但这不是关于指针向量的,而是关于引用指针向量的 #include <iostream> #include <vector> #include <algorithm> int main() { int a = 3; int b = 2; int c = 1; std::vector<int*> vec; vec.emplace_back(&a); vec.emplace_bac

已经有帖子了,但这不是关于指针向量的,而是关于引用指针向量的

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

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

    std::vector<int*> vec;
    vec.emplace_back(&a);
    vec.emplace_back(&b);
    vec.emplace_back(&c);

    std::sort(vec.begin(), vec.end(), [](const int* a, const int* b) {
        return *a < *b;
    });

    std::cout << "vec = " << *vec[0] << ", " << *vec[1] << ", " << *vec[2] << '\n';
    std::cout << "abc = " << a << ", " << b << ", " << c << '\n';
}
3个整数被放入
std::vector
中,然后根据指针后面的值进行排序

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

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

    std::vector<int*> vec;
    vec.emplace_back(&a);
    vec.emplace_back(&b);
    vec.emplace_back(&c);

    std::sort(vec.begin(), vec.end(), [](const int* a, const int* b) {
        return *a < *b;
    });

    std::cout << "vec = " << *vec[0] << ", " << *vec[1] << ", " << *vec[2] << '\n';
    std::cout << "abc = " << a << ", " << b << ", " << c << '\n';
}
我认为原因在于,在正确比较的同时,只分配地址而不是值。这里怎么了?为什么我不能对这个指向值的向量进行排序

下一部分是TL,DR,因为它显示了我的方法来解决这个问题。这是一项容易的任务,显示出它本身相当复杂,令人沮丧。指出这是不可能的。因此,接下来的部分,最初被认为是我尝试的介绍,现在可能被认为是不可能的原因



我的想法是制作一个指针类包装器来提供我自己的构造函数和赋值运算符<如果容器的大小很小(
),则代码>标准::排序()
的行为会有所不同

回调λ是用来评估排序的,但是需要调整元素的实际交换部分:C++标准库<代码>排序< /COD>不支持您这样做。


幸运的是,没有任何提示的快速排序(如预随机)只需几十行即可完成,因此这不是一项特别繁重的任务。

只需保留指针原始向量的副本,并将排序后的值复制到:

            std::vector<int*> original = vec;  // Do this before the std::sort


这听起来像是一个XY问题。你为什么试图让向量之外的变量发生变化?这是一个概念证明,还是你真的需要这样做?问问你自己:如果你撕下电话簿的页面并将其洗牌,这会改变任何人的电话号码吗?你的第一个代码的行为正是你所知道的你可以期待,其余的是tl;dr@NathanOliver有了它,我想做一个变量模板函数来对参数进行排序。我可以把它们复制到一个向量中,对向量进行排序,然后重新赋值,但我想知道是否有可能只做一个向量点。更好的标题应该是“如何对指向的值进行排序?”。排序指针是另外一回事(这也是你正在做的)。你是否总是保留你的答案时间戳,以防止做实际工作的人先得到它?@Slava:你知道吗?我花了22分钟才回答这个问题。我希望有人会说“你需要使用自己的排序函数来完成这项工作。”提供代码示例。可能已经有人在做这件事了,但你首先得到答案的方法是简单地说,你需要做这件事,而不提供实际的答案。同样的方法,你可以在这里写“我的答案稍后会在这里,我正在做”@斯拉瓦:如果你不认为这个答案是有用的,那么请你投票给我。我清楚地知道,OP知道如何根据问题的质量来编码判断,所以我的工作是指出这个方法。如果你用代码回答,我肯定会投票。“我想这是不可能的,因为没有人相信C++标准委员会会这么做。”是有用的。如果我这样做,我甚至不需要指针,因为我可以直接复制-排序-回写,这是我评论的我宁愿不做的。但是考虑到我最初的想法是不可能的,我要么这样做,要么自己排序。所以最后,在Bathsheba的答案和你的答案之间,这是一个性能与可维护性的问题。
template<typename T>
class assignement_pointer {
public:
    assignement_pointer(T& value) {
        this->m_ptr = &value;
        std::cout << "<T>& constructor\n";
    }
    assignement_pointer(const assignement_pointer& other) {
        this->m_ptr = other.m_ptr;
        std::cout << "copy constructor\n";
    }
    assignement_pointer(assignement_pointer&& other) {
        std::cout << "move assignement constructor >> into >> ";
        *this = std::move(other);
    }
    assignement_pointer& operator=(const assignement_pointer& other) {
        *this->m_ptr = *other.m_ptr;
        std::cout << "copy assignement operator\n";
        return *this;
    }
    assignement_pointer& operator=(assignement_pointer&& other) {
        std::swap(this->m_ptr, other.m_ptr);
        std::cout << "move assignement operator\n";
        return *this;
    }
    T& operator*() {
        return *this->m_ptr;
    }
    const T& operator*() const {
        return *this->m_ptr;
    }
private:
    T* m_ptr;
};
    ///...
    std::vector<assignement_pointer<int>> vec;
    vec.reserve(3);
    vec.emplace_back(assignement_pointer(a));
    vec.emplace_back(assignement_pointer(b));
    vec.emplace_back(assignement_pointer(c));

    std::cout << "\nsort()\n";
    std::sort(vec.begin(), vec.end(), [](const assignement_pointer<int>& a, const assignement_pointer<int>& b) {
        return *a < *b;
    });

    std::cout << "\nvec = " << *vec[0] << ", " << *vec[1] << ", " << *vec[2] << '\n';
    std::cout << "abc = " << a << ", " << b << ", " << c << '\n';
<T>& constructor
move assignement constructor >> into >> move assignement operator
<T>& constructor
move assignement constructor >> into >> move assignement operator
<T>& constructor
move assignement constructor >> into >> move assignement operator

sort()
move assignement constructor >> into >> move assignement operator
move assignement operator
move assignement operator
move assignement constructor >> into >> move assignement operator
move assignement operator
move assignement operator
move assignement operator

vec = 1, 2, 3
abc = 3, 2, 1
template<typename T>
class assignement_pointer {
public:
    assignement_pointer(T& value) {
        this->m_ptr = &value;
    }
    assignement_pointer(const assignement_pointer& other) = delete;
    assignement_pointer& operator=(const assignement_pointer& other) = delete;
    assignement_pointer(assignement_pointer&& other) {
        std::cout << "move assignement constructor >> into >> ";
        *this = std::move(other);
    }
    assignement_pointer& operator=(assignement_pointer&& other) {
        std::swap(this->m_ptr, other.m_ptr);
        std::cout << "move assignement operator\n";
        return *this;
    }
    T& operator*() {
        return *this->m_ptr;
    }
    const T& operator*() const {
        return *this->m_ptr;
    }
private:
    T* m_ptr;
};
 int main() {
    int a = 3;
    int b = 2;

    std::vector<assignement_pointer<int>> vec;
    vec.reserve(2); //to avoid re-allocations
    vec.emplace_back(assignement_pointer(a));
    vec.emplace_back(assignement_pointer(b));

    std::cout << "swap()\n";

    assignement_pointer<int> ptr_a{ a };
    assignement_pointer<int> ptr_b{ b };

    std::swap(ptr_a, ptr_b);

    std::cout << "\nptrs = " << *ptr_a << ", " << *ptr_b << '\n';
    std::cout << "a, b = " << a << ", " << b << '\n';
}
move assignement constructor >> into >> move assignement operator
move assignement constructor >> into >> move assignement operator
swap()
move assignement constructor >> into >> move assignement operator
move assignement operator
move assignement operator

ptrs = 2, 3
a, b = 3, 2
_Ty _Tmp = _STD move(_Left);
_Left = _STD move(_Right);
_Right = _STD move(_Tmp);
move assignement constructor >> into >> move assignement operator
move assignement operator
move assignement operator
            std::vector<int*> original = vec;  // Do this before the std::sort

            std::vector<int> xfer;
            for (auto ptr : vec) {
                xfer.push_back(*ptr);
            }
            auto it = std::begin(xfer);
            for (auto ptr : original) {
                *ptr = *it++;
            }
            std::cout << "abc = " << a << ", " << b << ", " << c << '\n';
abc = 1, 2, 3