指针是否有可能在没有任何数据副本的情况下由向量拥有?

Is it possible that a pointer gets owned by a vector without any data copy?

如果我有一个 C 类型的原始指针,是否可以从拥有指针数据的相同类型创建一个 std::vector 而无需任何数据复制(仅移动)?促使我问这个问题的是 data() 成员函数的存在 std::vector 这意味着向量的元素连续驻留在内存中的某个地方。

编辑:我必须补充一点,std::make_shared.

等功能的存在也加强了我的希望

不,std::vector 并非旨在能够 assume/utilize 预先存在的数组作为其内部存储。

是的,前提是您在获取指针之前创建并填充了 向量并且您不会

  1. 删除任何元素
  2. 你不会在vec.size() == vec.capacity() - 1时添加新元素,这样做改变元素的地址

示例

#include <iostream>

void fill_my_vector<std::vector<double>& vec){
    for(int i=0; i<300; i++){
        vec.push_back(i);
    }
}

void do_something(double* d, int size)
{ /* ..... */ }

int main(){
    std::vector<double> vec;
    fill_my_vector(vec);
    //You hereby promise to follow the contract conditions, then you are safe doing this

    double* ptr;
    int ptr_len = vec.size();
    ptr = &vec[0];

    //call do_something
    do_something(ptr, ptr_len);

    //ptr will be alive until this function scope exits
}

编辑

如果你的意思是从一个已经创建的数组中管理数据,你不能...vector 管理它自己的数组...它不能取得不是由它创建的数组的所有权class(向量)。

我认为这不可能直接实现,尽管您不是第一个错过此功能的人。没有非 const data 成员的 std::string 更加痛苦。希望这会在 C++17 中改变。

如果您自己分配缓冲区,则有一个解决方案。只需预先使用 std::vector 即可。例如,假设您有以下 C 风格的函数,

extern void
fill_in_the_numbers(double * buffer, std::size_t count);

那么您可以进行以下操作。

std::vector<double>
get_the_numbers_1st(const std::size_t n)
{
  auto numbers = std::vector<double> (n);
  fill_in_the_numbers(numbers.data(), numbers.size());
  return numbers;
}

或者,如果您不那么幸运并且您的 C 风格函数坚持自己分配内存,

extern double *
allocate_the_buffer_and_fill_in_the_numbers(std::size_t n);

你可以求助于 std::unique_ptr,但很遗憾。

std::unique_ptr<double[], void (*)(void *)>
get_the_numbers_2nd(const std::size_t n)
{
  return {
    allocate_the_buffer_and_fill_in_the_numbers(n),
    &std::free
  };
}