The question is simple: why can't I use propagate_const
for arrays?
The following line gives errors:
std::experimental::propagate_const<std::unique_ptr<int[]>> ptr = std::make_unique<int[]>(1);
The errors (gcc version 13.0):
/usr/local/include/c /13.0.0/experimental/propagate_const: In Instanziierung von »struct std::experimental::fundamentals_v2::__propagate_const_conversions<std::unique_ptr<int []> >«:
/usr/local/include/c /13.0.0/experimental/propagate_const:108:11: erfordert durch »class std::experimental::fundamentals_v2::propagate_const<std::unique_ptr<int []> >«
../../livews2223/l00/main.cpp:182:64: von hier erfordert
/usr/local/include/c /13.0.0/experimental/propagate_const:55:37: Fehler: no match for »operator*« (operand type is »std::unique_ptr<int []>«)
55 | = remove_reference_t<decltype(*std::declval<_Tp&>())>;
| ^~~~~~~~~~~~~~~~~~~~~
The the goal is to prevent that a const element-function can change array elements like:
struct A {
void foo() const {
a[0] = 2; // should not be possible
}
// std::experimental::propagate_const<std::unique_ptr<int[]>> a = std::make_unique<int[]>(2);
std::unique_ptr<int[]> a = std::make_unique<int[]>(2);
};
CodePudding user response:
unique_ptr<T[]>
is neither a pointer nor a pointer-like type. It's an array-like type. That's why it has operator[]
but not operator*
. It makes little sense to use *ptr
on an array (for language arrays, this accesses the first element, but using ptr[0]
makes it much more clear what's going on). So unique_ptr<T[]>
provides no such operator.
And therefore, it isn't pointer-like enough for propagate_const
to work.