为什么不能将const对象放入STL容器中?

时间:2011-12-31 00:04:13

标签: c++

请参阅下面的代码 - 我试图将const对象放入向量中。我知道答案是“STL容器需要对象可分配和复制构造”,但是,如果不引用标准,任何人都可以解释这样做的问题是什么?我不明白为什么这样的类无法复制(除了c ++不允许)。

所有它都是一个不允许更改的存储值 - 为什么不能将它放在一个向量中只是创建另一个这些对象?

#include <vector>

// Attempt 1
// /home/doriad/Test/Test.cxx:3:8: error: non-static const member ‘const int MyClass::x’, can’t use default assignment operator

// struct MyClass
// {
//   int const x;
//   MyClass(int x): x(x) {}
// };
// 
// int main()
// {
//   std::vector<MyClass> vec;
//   vec.push_back(MyClass(3));
//   return 0;
// }

// Attempt 2
// /home/doriad/Test/Test.cxx:28:23: error: assignment of read-only member ‘MyClass::x’
struct MyClass
{
  int const x;
  MyClass(int x): x(x) {}
  MyClass& operator= (const MyClass& other)
  {
    if (this != &other)
    {
      this->x = other.x;
    }

    return *this;
  }
};

int main()
{
  std::vector<MyClass> vec;
  vec.push_back(MyClass(3));
  return 0;
}

编辑:

可以使用std :: set和std :: list来完成此操作。我猜是std :: vector中的sort()函数使用赋值。这不是UB吗?

#include <set>

// Attempt 1
struct MyClass
{
  int const x;
  MyClass(int x): x(x) {}
  bool operator< (const MyClass &other) const;
};

bool MyClass::operator<(const MyClass &other) const
{
  if(this->x < other.x)
  {
    return true;
  }
  else if (other.x < this->x)
  {
    return false;
  }

}


int main()
{
  std::set<MyClass> container;
  container.insert(MyClass(3));
  return 0;
}

3 个答案:

答案 0 :(得分:7)

EDIT2 :(删除一堆不必工作的东西)C ++ 11标准规定了insertvector的{​​{1}}方法(以及默认值)对此问题的deque的实现)要求值类型为push_back,即值支持:

CopyAssignable

默认情况下,t= v; 成员的类和结构不是const,因此您要执行的操作无效。

此文档(n3173)解释了各种容器要求。

答案 1 :(得分:1)

一种可能的解决方案是存储指向矢量中对象的指针,因为指针是可分配的并且可以复制构造。

另一个可能的解决方案是声明没有const关键字的x,但要确保它不能通过封装修改(即你应该声明它是私有的,不要在构造函数之外的任何地方修改)。

答案 2 :(得分:0)

当你在std :: vector中放置一个MyClass类型的对象时,向量将复制该对象以供存储,而不是传递给它的对象。