1

I'm trying to use arrays in smart pointers, but when I cast smart_ptr to weak_ptr using Apple clang I get an error (I use -std=c++17).

error: cannot initialize a member subobject of type 'std::weak_ptr<int []>::element_type *' (aka 'int (*)[]') with an lvalue of type 'std::shared_ptr<int []>::element_type *const' (aka 'int *const')
    : __ptr_(__r.__ptr_),

Here is an example of code I'm trying to compile.

std::shared_ptr<int[]> ptr(new int[5]);
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;

std::weak_ptr<int[]> weakPtr(ptr);

std::cout << ptr[0] << std::endl;

P.S. I can't use std::array as I'm implementing my own container class.

s1ava
  • 13
  • 2

1 Answers1

0

This seems to be a bug, where weak_ptr<T>::element_type should be defined as remove_extend_t<T>, but it is currently defined as T. On the other side, share_ptr<T>::element_type is correctly defined as remove_extend_t<T>.

This inconsistent caused the underlying type of shared_ptr<T[]> is T*, where the underlying type of weak_ptr<T[]> is T(*)[], thus you cannot assign the shared_ptr<T[]> to weak_ptr<T[]> as expected.

The bug was fixed in this commit: LWG3001 and should be included in a future release.


A work around is to probably use shared_ptr<std::array<int, 5>> and deduce the type for std::weak_ptr with weak_ptr weakPtr(ptr).

Note you will not be able to use shared_ptr::operator [] directly anymore. Instead, you would need to do get the element with (*ptr)[N].

Ranoiaetep
  • 5,872
  • 1
  • 14
  • 39