double * values; // instead of this,
std::vector<double> values; // I want this.
Run Code Online (Sandbox Code Playgroud)
我正在使用的API提供结果作为double*指针.我想用这个std::vector<double>类型包装它.
Set*_*gie 30
您无法将数组包装在向量中,并期望向量在该数组上运行.你可以做的最好的事情是给出向量double*和值的数量,这将使向量复制每个元素并将其放在自身中:
int arrlen = 0;
// pretending my_api takes arrlen by reference and sets it to the length of the array
double* dbl_ptr = my_api(arrlen);
vector<double> values(dbl_ptr, dbl_ptr + arrlen);
// note that values is *not* using the same memory as dbl_ptr
// so although values[0] == dbl_ptr[0], &values[0] != &dbl_ptr[0]
Run Code Online (Sandbox Code Playgroud)
而且,正如Praetorian所说,如果你使用的API希望你在使用后释放内存,你可能会对智能指针感兴趣.请参阅Praetorian的回答.
Eth*_*eal 11
其他人建议你不能将数组包装在一个向量中,但这根本不是真的; 想一想,矢量有一个数组作为它的底层数据容器!在我想出一个可行的解决方案之前,我已经尝试了很长时间.需要注意的是,您必须在使用后将指针归零,以避免双重释放内存.
#include <vector>
#include <iostream>
template <class T>
void wrapArrayInVector( T *sourceArray, size_t arraySize, std::vector<T, std::allocator<T> > &targetVector ) {
typename std::_Vector_base<T, std::allocator<T> >::_Vector_impl *vectorPtr =
(typename std::_Vector_base<T, std::allocator<T> >::_Vector_impl *)((void *) &targetVector);
vectorPtr->_M_start = sourceArray;
vectorPtr->_M_finish = vectorPtr->_M_end_of_storage = vectorPtr->_M_start + arraySize;
}
template <class T>
void releaseVectorWrapper( std::vector<T, std::allocator<T> > &targetVector ) {
typename std::_Vector_base<T, std::allocator<T> >::_Vector_impl *vectorPtr =
(typename std::_Vector_base<T, std::allocator<T> >::_Vector_impl *)((void *) &targetVector);
vectorPtr->_M_start = vectorPtr->_M_finish = vectorPtr->_M_end_of_storage = NULL;
}
int main() {
int tests[6] = { 1, 2, 3, 6, 5, 4 };
std::vector<int> targetVector;
wrapArrayInVector( tests, 6, targetVector);
std::cout << std::hex << &tests[0] << ": " << std::dec
<< tests[1] << " " << tests[3] << " " << tests[5] << std::endl;
std::cout << std::hex << &targetVector[0] << ": " << std::dec
<< targetVector[1] << " " << targetVector[3] << " " << targetVector[5] << std::endl;
releaseVectorWrapper( targetVector );
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以创建一个继承自vector的类,并在销毁时将指针归零:
template <class T>
class vectorWrapper : public std::vector<T>
{
public:
vectorWrapper() {
this->_M_impl _M_start = this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = NULL;
}
vectorWrapper(T* sourceArray, int arraySize)
{
this->_M_impl _M_start = sourceArray;
this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = sourceArray + arraySize;
}
~vectorWrapper() {
this->_M_impl _M_start = this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = NULL;
}
void wrapArray(T* sourceArray, int arraySize)
{
this->_M_impl _M_start = sourceArray;
this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = sourceArray + arraySize;
}
};
Run Code Online (Sandbox Code Playgroud)
const int N = 10; // Number of elements in your array
std::vector<double> vec_values(values, values + N);
Run Code Online (Sandbox Code Playgroud)
这会将数据复制values到a std::vector.
其他答案显示如何制作返回数组的副本并创建一个vector,但假设API为数组分配内存并期望调用者删除它,您可能还需要考虑将数组插入智能指针并使用它原样.
int numValues;
std::unique_ptr<double[]> values( apiFunction( &numValues ) );
Run Code Online (Sandbox Code Playgroud)
您仍然可以将其复制到一个vector但是如果您执行上述步骤,则无需担心删除返回的数组.
如果使用 C++11,您可以使用std::vector<std::reference_wrapper<double>>.
#include <functional> // std::reference_wrapper
#include <vector>
#include <iostream>
#include <numeric> // std::iota
#include <random> // std::mt19937
#include <algorithm> // std::shuffle
int main() {
const int N = 10; // Number of elements in your array
double values[N];
std::iota(values, values+N, -4.0);
std::vector<std::reference_wrapper<double>> v(values, values + N);
std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()});
std::cout << "Contents of the array: ";
for(auto i=0; i < N; ++i) std::cout << values[i] << ' ';
std::cout << '\n';
std::cout << "Contents of the array, shuffled: ";
for(auto i: v) std::cout << i << ' ';
std::cout << '\n';
std::cout << "Change values using the vector shuffled\n";
auto j = 44.;
for(double& i: v) i = ++j;
std::cout << "Contents of the array, shuffled: ";
for(auto i: v) std::cout << i << ' ';
std::cout << '\n';
std::cout << "Contents of the array: ";
for(auto i=0; i < N; ++i) std::cout << values[i] << ' ';
std::cout << '\n';
}
Run Code Online (Sandbox Code Playgroud)
可能的输出:
Contents of the array: -4 -3 -2 -1 0 1 2 3 4 5
Contents of the array, shuffled: 1 3 -2 0 -3 5 -4 4 -1 2
Change values using the vector shuffled
Contents of the array, shuffled: 45 46 47 48 49 50 51 52 53 54
Contents of the array: 51 49 47 53 48 45 54 46 52 50
Run Code Online (Sandbox Code Playgroud)
优点:零拷贝
参考:https://en.cppreference.com/w/cpp/utility/function/reference_wrapper
| 归档时间: |
|
| 查看次数: |
35674 次 |
| 最近记录: |