好的,所以我最近了解到(a)std :: vector按定义/标准使用连续内存,因此(b)&(v [0])是那个连续内存块的地址,你就是可以读/写为old-skool C-array。像...
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-array对象,我可以使用这样的代码:
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)没有额外的时间将所有数据的冗余副本插入到向量中。注意&#34;只是改变你的愚蠢计算,蠢货和#34;是不够的,因为有成千上万的这样的功能/方法表现出这种模式并不在我的控制之下,即使它们太多而无法改变所有这些模式。
另请注意,因为我只对const std :: vector&amp;使用,不用担心我的原始内存需要调整大小,甚至修改。我想要一个类似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-array和一个大小的指针构造,并且(b)有目的地做了没有实现非const方法(push_back,resize等),所以即使typename为const_vector的对象实际上不是const对象,只提供const方法的接口使它实际上是const(以及任何错误的尝试修改将在编译时捕获)?
更新:有点乱搞表明这个&#34;解决了&#34;我的问题是Windows实现的std :: vector:
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;
};
但当然&#34;解决方案&#34;是可怕的,因为(a)它没有通过执行resize()或push_back()提供对基类删除原始内存的保护(除了只构造const vector_tweaker()的细心用户) - 和(b)它是特定于std :: vector的特定实现,并且必须为其他实现重新实现 - 如果其他平台确实只将其std :: vector成员数据声明为protected:就像microsoft所做的那样(似乎是一个坏主意)。
答案 0 :(得分:3)
您可以尝试使用std::reference_wrapper<>
:
SomeClass cary[100];
// ...
std::vector<std::reference_wrapper<SomeClass>> cv;
cv.push_back(cary[i]); // no object copying is done, reference wrapper is stored
或者没有C11,您可以为字节创建此类模板类的特化 - char。然后对于来自char*
C-array的构造函数,您可以使用::memcpy
:不幸的是,它会使用两倍的内存。
::memcpy(&v[0], c_arr, n);
这样的事情:
template <typename T> class MyVector : public std::vector<T> {
};
template <> class MyVector<char> : public std::vector<char> {
public:
MyVector<char>(char* carr, size_t n) : std::vector<char>(n) {
::memcpy(&operator[](0), carr, n);
}
};
我建议 - 尽可能将所有C数组替换为向量,然后不需要额外的复制。