3

I have C++17 turned on and clang from Android NDK and I expect the below to work

std::shared_ptr<int[]> sp(new int[5]());

but I get

error: no matching constructor for initialization of 'std::shared_ptr<int []>'

How do I fix this ? This works fine on MSVC

rstr1112
  • 308
  • 4
  • 13
  • 1
    What Clang version? This works since Clang 11. – HolyBlackCat Jun 30 '21 at 07:07
  • Instead of explicit `new` I suggest using `std::make_shared`. And instead of using a C style array you'd better use `std::array` or `std::vector`. – datenwolf Jun 30 '21 at 07:11
  • @HolyBlackCat that probably explains it. The NDK I'm using ships with clang 9 – rstr1112 Jun 30 '21 at 07:12
  • @RoQuOTriX it's a C++ 17 feature – rstr1112 Jun 30 '21 at 07:13
  • @datenwolf I have specifc reason – rstr1112 Jun 30 '21 at 07:13
  • @RoQuOTriX dynamic arrays wrapped by a shared_ptr was not possible pre C++17. std::shared_ptr – rstr1112 Jun 30 '21 at 07:15
  • @datenwolf I need to able to pass the same information from the source that is over an ABI stable bridge so int* only. Using std::vector and std::array will force me to copy it which I don't want to do. – rstr1112 Jun 30 '21 at 07:20
  • 1
    for pre c++17 you'd need to use `std::shared_ptr sp(new int[5](), [](int* p){ delete[] p; });`. Note that shared pointers to arrays don't require clang 11 but libc++ 11, clang with libstdc++ works in earlier versions (though I'm not sure if you end up with the correct deleter being generated in this case) – Alan Birtles Jun 30 '21 at 07:31
  • @AlanBirtles my question says I'm using C++17 and still hit the error in CLANG – rstr1112 Jun 30 '21 at 08:55
  • just because you are asking for C++17 doesn't mean it is fully implemented in the compiler and standard library, as stated above it looks like `shared_ptr`s to arrays weren't implemented in libc++ until version 11 so if you're using that it wont work. See the line for `P0414R2` at https://en.cppreference.com/w/cpp/compiler_support – Alan Birtles Jun 30 '21 at 08:59
  • @rstr1112: I don't think ABI concerns are justified, you're using `std::shared_ptr` already. And whereever you need to expose the naked pointer (`int*`) you can just invoke the `std::{array,vector}::data()` accessor, i.e. `auto sp = std::make_shared>(); /* … */; foo(sp->data());`. – datenwolf Jun 30 '21 at 11:00
  • @datenwolf : I don't mean I'll pass shared_ptr across the boundary. I'll wrap the raw pointer with a shared_ptr once it crosses the bridge – rstr1112 Jun 30 '21 at 19:40

0 Answers0