5

I have an existing pybind11::array_t, and need to do a copy-construction. Is there a function inside pybind11 that allows me to do a deep copy of an array_t?

I know that I could create a new array_t, size it properly, and then copy the original data into it, but was wondering if there exists already a method to do this that hides these passages.

Hari
  • 718
  • 3
  • 9
  • 30
fnrizzi
  • 51
  • 2
  • are you sure `auto copy = original;` doesn't do what you want? – Caleth Jun 13 '19 at 08:36
  • 1
    Yes, because that involves a shallow copy. This snippet prints the same addresses: `using py_arr = pybind11::array_t; py_arr a; auto b = a; std::cout << b.data() << " " << a.data() << std::endl;` – fnrizzi Jun 13 '19 at 09:54

1 Answers1

1

the default copy constructor does a deep copy, people are actually trying to avoid this :)

To use the copy constructor, you can go through the buffer

using py_arr = pybind11::array_t<double>;
py_arr a;

// do stuff with a, fill it and everything...

auto buffer = a.request(); 
py_arr b = py_arr(buffer);

std::cout << b.data() << " " << a.data() << std::endl; // this won't return the same address twice
Christian
  • 1,162
  • 12
  • 21
  • Thanks for the comment. (a) I agree on the buffer option. However, the ```request``` is a const method, so in case you have a function somewhere that accepts ```const pybind11::array_t & a```, and one would want to create a deep copy of it, one would need to ```const_cast```. That is why I was asking for deep copy constructor or similar method. (2) The default copy constructor of ```py::array_t``` does a **shallow** copy. ```using py_arr = pybind11::array_t; py_arr a; py_arr b(a); std::cout << b.data() << " " << a.data() << std::endl;``` prints the same address. – fnrizzi Jun 18 '19 at 18:52
  • If there is no other option, I could use the buffer but I was hoping for an alternative, more compact way that works for const-cases too. – fnrizzi Jun 18 '19 at 18:54
  • Oh I see, you could overload the `=` operator (see [this answer](https://stackoverflow.com/a/4421715/3283333)) with the implementation I just gave, that should sort you out right ? – Christian Jun 22 '19 at 10:12
  • Hi, sorry for the late reply :) Yes, I could overload that but then it would break the semantics. There are places where I need shallow copy and places where I need deep copy. I think i I will just use the buffer, even though I have to ```const_cast```. Thanks for your help! – fnrizzi Jul 11 '19 at 13:07