一个元素不能改变的非守恒向量
A nonconst vector whose elements cannot change - alternatives
我痴迷于制作真正应该是const
的const
,即使这样做看起来有点痛苦。
在这种情况下,我想要一个vector<int>
,我可以向其中添加元素,但不能更改其现有元素。问题是不允许使用vector<const int>
。
其目的不仅是防止我的类的用户修改他们不应该修改的东西(这可以通过成员函数中的const
迭代器轻松完成)。同样重要的是,我自己以后不会在自己的代码中做我不打算做的事情。
我找到了两个替代方案:
-
请改用
deque<const int>
。 -
创建我自己的向量类来包装实际的
vector
,如下所示(我在这里为int
这样做,但实际上为了通用性,我会使用模板)class my_vector { private: std::vector<int> vec; public: std::vector<int>::const_iterator cbegin() { return vec.cbegin(); } std::vector<int>::const_iterator cend() { return vec.cend(); } void push_back(int i) { vec.push_back(i); } };
您会推荐以下哪种想法(或其他想法)?编译器会把第二个替代方案变成和直接使用向量一样快的代码吗?
你的痴迷是可以理解的,我并不反对,但除非你有迫切的需求,否则所需的努力可能不值得付出。
假设您根据设计要求选择vector
作为容器,我不建议将其更改为deque
或任何其他类型。这只会让未来的读者(可能是你自己)感到困惑,否则也是一种糟糕的做法。
如果我们使用您的包装器解决方案,您将不得不hide覆盖可以修改向量的所有成员,这是一个问题,因为有许多方法用于访问和修改,如operator[]
、at()
、front()
、back()
。这可能会让未来的读者感到困惑,因为他们已经习惯了"标准"的vector
行为。
顺便问一下,你确定deque<const int> foo;
有效吗?我得到以下错误:
error: invalid conversion from 'const void*' to 'void*'
编辑我似乎没有完全回答你的问题。如果让选择一个,我会选择包装器方法。
我更喜欢私有继承,因为这类标准容器几乎完全符合我的需求。公共继承通过指向基类的指针导致切片或非虚拟销毁。作文需要额外打字。
私人继承和using
的使用很好地表达了您的意图。
这是一个例子:
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
class my_vector : private std::vector<int> {
// Utility type
typedef std::vector<int> base;
public:
// Types I don't need to tweak:
using base::value_type;
using base::allocator_type;
using base::size_type;
using base::difference_type;
using base::const_reference;
using base::const_pointer;
using base::const_iterator;
using base::const_reverse_iterator;
// Types I do need to tweak:
typedef const_reference reference;
typedef const_pointer pointer;
typedef const_iterator iterator;
typedef const_reverse_iterator reverse_iterator;
// Constructors
// Implicit constructors OK
// Destructors
// Implicit destructors OK
// Assignment
// Implicit assignment OK
// Methods that I don't need to tweak:
using base::assign;
using base::get_allocator;
using base::empty;
using base::size;
using base::max_size;
using base::reserve;
using base::capacity;
using base::clear;
using base::push_back;
using base::pop_back;
using base::swap;
// Methods I need to tweak
const_reference at( size_type pos ) const { return base::at(pos); }
const_reference operator[](size_type pos) const { return base::operator[](pos); }
const_reference front() const { return base::front(); }
const_reference back() const { return base::back(); }
const_iterator begin() const { return base::begin(); }
const_iterator end() const { return base::end(); }
const_reverse_iterator rbegin() const { return base::rbegin(); }
const_reverse_iterator rend() const { return base::rend(); }
// Methods I need to delete:
// base::insert;
// base::erase;
// base::resize;
};
int main () {
my_vector m;
m.push_back(1);
m.push_back(2);
m.push_back(3);
my_vector m2;
m2 = m;
std::copy(m2.begin(), m2.end(), std::ostream_iterator<int>(std::cout, "n"));
}
标准容器没有什么神奇之处。如果您需要一个具有与标准容器不同特性的容器,请编写自己的容器。如果其中一个标准容器接近您所需要的,请将其用作内部实现。简言之,my_vector
就是我们要走的路。
- 变量没有改变?通过向量的函数调用
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- C++在不同线程中改变向量
- 在向量内更改变量的值不会改变其在向量外的值
- 为什么 GCC 不能假设 std::vector::size 在这个循环中不会改变?
- MFC:你能在CDateTimeCtrl中改变自旋的加速度吗?
- 你能把一个向量<int64>投射到一个向量<uint8>吗
- 为什么 c++ 不能打印向量 B[0]?
- C++ 不能在cout中使用向量和字符串文字
- 目标C++不能在枚举块中使用向量push_back
- 对于循环增量器不能用作字符串向量的索引
- 为什么我不能返回向量<向量<int>>(进程返回 -1073741819 (0xC0000005))
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 为什么左值不能改变自己。左值用户是什么意思?
- 分配矩阵列标准偏差的向量正在改变其值(RcppArmadillo)
- 应该很琐碎,为什么我不能改变我的向量的值
- 一个元素不能改变的非守恒向量
- 你能改变指针指向的大小吗?
- 不能改变Cocos2d-x MenuItemToggle元素的不透明度
- 不能改变变量的值