Date: Fri, 8 Dec 2023 15:30:07 -0800
Here's a compelling argument as to why we should allow assignment on
array<T const, 0>:
struct myclass
{
mutable int i;
myclass const & operator=(myclass const &other) const
{
i = other.i;
return *this;
}
};
int main()
{
std::array<myclass const, 1> arr1;
std::array<myclass const, 1> arr2;
arr1 = arr2;
} This works fine, both in libc++ *and* libstdc++, however if the size is
changed to 0, only libc++ breaks.
The way I see it:
Either:
1. check if operator= works for const lvalues (normally no, but this isn't
guaranteed because of mutables)
2. Allow it always.
On Fri, Dec 8, 2023 at 1:59 PM Ryan Nicholl <rnicholl_at_[hidden]> wrote:
> I feel like that particular point is more about the fact that new T[0]
> treats the size as a runtime argument, hence the requirement that T be
> default constructible, even if the default constructor isn't run. I feel
> like we don't need to apply that logic to std::array, since we know the
> size at compile time.
>
> On Fri, Dec 8, 2023 at 1:04 PM Jens Maurer <jens.maurer_at_[hidden]> wrote:
>
>>
>>
>> On 08/12/2023 00.27, Arthur O'Dwyer wrote:
>> > On Thu, Dec 7, 2023 at 2:00 AM Jens Maurer <jens.maurer_at_[hidden]
>> <mailto:jens.maurer_at_[hidden]>> wrote:
>>
>> > A consistency point of view:
>> > T * p = new T[n];
>> > (where n might be a constant or not)
>> > is now required to have T default constructible even if n = 0. CWG
>> 2102 <https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2102>.
>> >
>> >
>> > That's a different (and perhaps even deeper) can of worms, right?
>>
>> Sure, but it's also about empty arrays.
>>
>> Jens
>>
>>
>> > We currently lack specification for whether any of these expressions
>> are supposed to work:
>> > std::array<const int, 0> ca = {}; // OK
>> > std::array<const int, 0> cb; // unclear; libc++ and *Microsoft*
>> reject; *libstdc++* accepts
>> > ca = ca; // unclear; libc++ and Microsoft reject; libstdc++ accepts
>> > ca.fill(42); // unclear; libc++ and *libstdc++* reject; *Microsoft*
>> accepts
>> > ca.swap(ca); // unclear; libc++ and libstdc++ reject; Microsoft
>> accepts
>> > Is there yet an LWG issue to clarify the well-formedness of the
>> "mutating" member functions of array<const T, N>?
>> >
>> > Thanks,
>> > Arthur
>>
>
array<T const, 0>:
struct myclass
{
mutable int i;
myclass const & operator=(myclass const &other) const
{
i = other.i;
return *this;
}
};
int main()
{
std::array<myclass const, 1> arr1;
std::array<myclass const, 1> arr2;
arr1 = arr2;
} This works fine, both in libc++ *and* libstdc++, however if the size is
changed to 0, only libc++ breaks.
The way I see it:
Either:
1. check if operator= works for const lvalues (normally no, but this isn't
guaranteed because of mutables)
2. Allow it always.
On Fri, Dec 8, 2023 at 1:59 PM Ryan Nicholl <rnicholl_at_[hidden]> wrote:
> I feel like that particular point is more about the fact that new T[0]
> treats the size as a runtime argument, hence the requirement that T be
> default constructible, even if the default constructor isn't run. I feel
> like we don't need to apply that logic to std::array, since we know the
> size at compile time.
>
> On Fri, Dec 8, 2023 at 1:04 PM Jens Maurer <jens.maurer_at_[hidden]> wrote:
>
>>
>>
>> On 08/12/2023 00.27, Arthur O'Dwyer wrote:
>> > On Thu, Dec 7, 2023 at 2:00 AM Jens Maurer <jens.maurer_at_[hidden]
>> <mailto:jens.maurer_at_[hidden]>> wrote:
>>
>> > A consistency point of view:
>> > T * p = new T[n];
>> > (where n might be a constant or not)
>> > is now required to have T default constructible even if n = 0. CWG
>> 2102 <https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2102>.
>> >
>> >
>> > That's a different (and perhaps even deeper) can of worms, right?
>>
>> Sure, but it's also about empty arrays.
>>
>> Jens
>>
>>
>> > We currently lack specification for whether any of these expressions
>> are supposed to work:
>> > std::array<const int, 0> ca = {}; // OK
>> > std::array<const int, 0> cb; // unclear; libc++ and *Microsoft*
>> reject; *libstdc++* accepts
>> > ca = ca; // unclear; libc++ and Microsoft reject; libstdc++ accepts
>> > ca.fill(42); // unclear; libc++ and *libstdc++* reject; *Microsoft*
>> accepts
>> > ca.swap(ca); // unclear; libc++ and libstdc++ reject; Microsoft
>> accepts
>> > Is there yet an LWG issue to clarify the well-formedness of the
>> "mutating" member functions of array<const T, N>?
>> >
>> > Thanks,
>> > Arthur
>>
>
Received on 2023-12-08 23:30:21