好的,最近我了解到 (a) 标准库中的 std::vector 定义是使用连续的内存空间,因此 (b) &(v[0]) 是该连续内存块的地址,在这个地址上你可以像操作旧式 C 数组一样进行读写。就像这样...
void printem(size_t n, int* iary)
{ for (size_t i=0; i<n; ++i) std::cout << iary[i] << std::endl; }
void doublem(size_t n, int* iary)
{ for (size_t i=0; i<n; ++i) iary[i] *= 2; }
std::vector<int> v;
for (size_t i=0; i<100; ++i) v.push_back(i);
int* iptr = &(v[0]);
doublem(v.size(), iptr);
printem(v.size(), iptr);
好的,那很棒,但我想朝另一个方向发展。我有很多现有的代码,例如
double computeSomething(const std::vector<SomeClass>& v) { ... }
如果我有一个C对象数组,我可以使用如下代码:
SomeClass cary[100]; // 100*sizeof(SomeClass)
// populate this however
std::vector<SomeClass> v;
for (size_t i=0; i<100; ++i) v.push_back(cary[i]);
// now v is also using 100*sizeof(SomeClass)
double x = computeSomething(v);
我希望做到这一点(a)没有额外的空间和(b)没有插入所有那些数据的冗余副本所需的额外时间。请注意,“只是更改你愚蠢的computeSomething,白痴”是不够的,因为有成千上万个这样的函数/方法展示了这种模式,它们不在我的控制范围内,即使它们也太多了,无法全部更改。
还要注意的是,因为我只关心const std::vector&的使用,所以我的原始内存永远不需要调整大小,甚至不需要修改。 我想要像const std::vector构造函数之类的东西,但我不知道语言是否允许对类的const实例进行特殊构造,例如:
namespace std { template <typename T> class vector {
vector() { ... }
vector(size_t n) { ... }
vector(size_t n, const T& t) { ... }
const vector(size_t n, T*) { ... } // can this be done?
...
如果不可能的话,那么可以考虑从std::vector派生出一个容器,称为std::const_vector,它(a)可以从指向c数组和大小的指针构造,(b)有意地没有实现非const方法(push_back、resize等),因此即使具有typename为const_vector的对象实际上不是const对象,只提供const方法的接口也使其实际上成为了const(任何错误的修改尝试都将在编译时被捕获)。更新:一些测试表明,这种方法“解决”了我的关于std::vector在Windows实现方面的问题。
template <typename T>
class vector_tweaker : public std::vector<T> {
public:
vector_tweaker(size_t n, T* t) {
_saveMyfirst = _Myfirst;
_saveMylast = _Mylast;
_saveMyend = _Myend;
_Myfirst = t;
_Mylast = t + n;
_Myend = t + n;
}
~vector_tweaker() {
_Myfirst = _saveMyfirst;
_Mylast = _saveMylast;
_Myend = _saveMyend; // and proceed to std::vector destructor
}
private:
T* _saveMyfirst;
T* _saveMylast;
T* _saveMyend;
};
当然,“解决方案”是丑陋的,因为(a)它无法防止基类通过resize()或push_back()删除原始内存(除非仅构造const vector_tweaker()并小心使用);(b)它特定于std::vector的特定实现,并且必须重新实现其他平台(如果确实只声明其std::vector成员数据为受保护的话,就像微软那样,似乎不是一个好主意)。
std::array
,再过一个月可能会是std::deque
。 “C ++方式”是传递一对迭代器,虽然专家们现在正在转向范围(这实际上只是一个包含一对迭代器的结构)。 - Ben Voigtdata
指针或&v[0]
更改向量。 - Shoe