【问题标题】:How to sort a vector containing const values如何对包含 const 值的向量进行排序
【发布时间】:2020-01-24 16:47:44
【问题描述】:

我有一个这样设置的向量,我想对其进行排序:

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

using namespace std;

int main()
{
    const int a =10;
    int b = 20;
    pair<const int, int> constPair1(a,b);
    b=30;
    pair<const int, int> constPair2(a,b);
    vector<pair<const int, int>> vec{constPair1,constPair2};
    sort(vec.begin(),vec.end());

    return 0;
}

不幸的是,由于const 值,上述排序将无法编译。有什么办法可以对这个向量进行排序吗?还是我被困在创建新向量并复制值?

【问题讨论】:

  • 为什么会有const 变量的向量? vector 本质上是一个动态容器,不是吗?
  • 这将是一个必须接受const 值的容器的底层实现。
  • 你可以使用std::map吗? value_type 是 std::pair 并且默认排序。拥有 std::map. 将是微不足道的
  • @DanShield 我认为地图行不通。 23.2.4.7 说容器的类型要求适用于映射的键和值类型,并且 const 值不可分配或移动。
  • @DanShield 这实际上被用作地图专业化的底层实现,因此使用 std::map 没有意义。

标签: c++ sorting vector


【解决方案1】:

在 C++03 中,std::vector 中的元素在 c++ 中必须是可复制赋值和可复制构造的。具有 const 成员的对不满足该要求,因此无效。编译器拒绝它是对的。

在 C++11 中,std::vector 中的元素必须是可移动赋值和可移动构造的。带有 const 成员的对不能移动,因此会导致无效代码。

【讨论】:

  • 您对此完全确定吗?因为我可以制作unique_ptr 的向量就好了,而且它们既不能复制分配也不能复制构造。也许您指的是 C++03?
  • Copy-assignable 和 copy-constructible 是 C++03 中的要求。在 C++11 中,这已更改为可移动构造和可移动分配。 std::unique_ptr 是这些要求的模型,因此可以放入 C++11 中的向量中。但是,常数也是不可移动的。
  • 有趣的是,GCC 4.7 似乎很高兴有一个包含 const 内容的对向量,尽管它不允许您对它们进行排序。 VS2013 很乐意创建 const int 的向量并对其进行排序,但我猜它们的情况略有不同。
  • @Rook 模板参数类型的类型要求只有在代码实际实例化时才会检查。只要您不使用任何调用复制或赋值运算符(或移动等效项)的方法,它就会编译。严格来说,我会说这种行为是未定义的,因为它违反了类的要求。
  • 编译器实际上并没有拒绝向量,只是尝试使用排序来移动东西
【解决方案2】:

我决定使用const_castoverride=swap 来进行排序:

template <class KEY, class VALUE>
class Wrapper {
    std::pair<const KEY, VALUE> d_data;

  public:
    Wrapper& operator=(const Wrapper &rhs) {
        const_cast<KEY&>(d_data.first) = rhs.d_data.first;
        d_data.second = rhs.d_data.second;
    }

    std::pair<const KEY, VALUE>& data() { return d_data; }
    std::pair<const KEY, VALUE> const& data() const { return d_data; }
};

template <class KEY, class VALUE>
void swap(Wrapper<KEY, VALUE>& a, Wrapper<KEY, VALUE>& b) {
    using std::swap;
    swap(const_cast<KEY&>(a.data().first), const_cast<KEY&>(b.data().first));
    swap(a.data().second, b.data().second);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-12
    • 2018-01-08
    • 1970-01-01
    • 2019-05-25
    • 2013-04-29
    • 1970-01-01
    • 2021-07-05
    相关资源
    最近更新 更多