Date: Tue, 13 Jun 2023 17:19:56 +0200
On 13/06/2023 11.11, Marcin Jaczewski wrote:
> wt., 13 cze 2023 o 10:44 Federico Kircheis via Std-Proposals
> <std-proposals_at_[hidden]> napisał(a):
>>
>> On Tue, Jun 13, 2023 at 10:39:46AM +0200, Marcin Jaczewski wrote:
>>> wt., 13 cze 2023 o 10:34 Federico Kircheis via Std-Proposals
>>> <std-proposals_at_[hidden]> napisał(a):
>>>>
>>>>
>>>> Hello to everyone, please consider following snippet
>>>>
>>>> ----
>>>> #include <vector>
>>>> #include <memory>
>>>>
>>>> struct s{
>>>> std::vector<std::unique_ptr<int>> d;
>>>> };
>>>>
>>>> static_assert(!std::is_copy_assignable<std::unique_ptr<int>>::value);
>>>> static_assert(std::is_copy_assignable<std::vector<std::unique_ptr<int>>>::value);
>>>> static_assert(std::is_copy_assignable<s>::value);
>>>>
>>>> void bar(){
>>>> s s1;
>>>> // fails, as expected, but inconsistent with is_copy_assignable
>>>> auto s2 = s1;
>>>> }
>>>> ----
>>>>
>>>> Doesn't the second static_assert bother anyone?
>>>>
>>>> Vector is always is_copy_assignable, but in fact it is a compile-time
>>>> error (auto s2 = s1) does not compile.
>>>>
>>>> Depending on the compiler, compiler errors are also verbose
>>>> (https://godbolt.org/z/3E49c4oT7) and not necessarily easy to understand
>>>> (immagine if s is part of a class hierarchy or a member of another
>>>> class...)
>>>> q
>>>> An improvement for the end-user is to delete the copy-constructor of s
>>>> by hand, it does not change what programs are valid, but the error
>>>> message is much more easy to understand.
>>>>
>>>> But it does not fix the underlying issue, and the fact that one cannot
>>>> simply follow the "rule of 0" and let the compiler use the defaulted
>>>> copy and move constructors without writing them down.
>>>>
>>>> Does anyone know if there is already a paper trying to fix this issue,
>>>> or if there was one and was rejected?
>>>> I assume the main difficulty is specifying something that also works
>>>> with forward-declared types.
>>>>
>>>> Thanks
>>>>
>>>> Federico
>>>>
>>>
>>> You can't have cake and eat it too, "fix" would need to ban
>>> use of forward declared types in vector:
>>> ```
>>> struct Foo
>>> {
>>> std::vector<Foo> f;
>>> };
>>> ```
>>> Now this works fine, after it would not.
>>
>> Wouldn't it be possible to have vector play well with is_copy_assignable
>> (ie delete copy-constructor if contained type is not copyable) if the
>> type is not forward-declared?
>>
>> Granted, is_copy_assignable could still be wrong with forward-declared
>> types, but it would at least work correctly for more use-cases.
>
> This will fix nothing, as the vector needs to behave the same
> whether the type is forward declared or not. You do not control it
> as in some TU it will use forward declared type and in others it will not.
> You will get multiple ODR problems where you check this condition.
I am not sure I get your point.
The behavior of vector would not change, as "auto s2 = s1;" would
continue not to compile.
> wt., 13 cze 2023 o 10:44 Federico Kircheis via Std-Proposals
> <std-proposals_at_[hidden]> napisał(a):
>>
>> On Tue, Jun 13, 2023 at 10:39:46AM +0200, Marcin Jaczewski wrote:
>>> wt., 13 cze 2023 o 10:34 Federico Kircheis via Std-Proposals
>>> <std-proposals_at_[hidden]> napisał(a):
>>>>
>>>>
>>>> Hello to everyone, please consider following snippet
>>>>
>>>> ----
>>>> #include <vector>
>>>> #include <memory>
>>>>
>>>> struct s{
>>>> std::vector<std::unique_ptr<int>> d;
>>>> };
>>>>
>>>> static_assert(!std::is_copy_assignable<std::unique_ptr<int>>::value);
>>>> static_assert(std::is_copy_assignable<std::vector<std::unique_ptr<int>>>::value);
>>>> static_assert(std::is_copy_assignable<s>::value);
>>>>
>>>> void bar(){
>>>> s s1;
>>>> // fails, as expected, but inconsistent with is_copy_assignable
>>>> auto s2 = s1;
>>>> }
>>>> ----
>>>>
>>>> Doesn't the second static_assert bother anyone?
>>>>
>>>> Vector is always is_copy_assignable, but in fact it is a compile-time
>>>> error (auto s2 = s1) does not compile.
>>>>
>>>> Depending on the compiler, compiler errors are also verbose
>>>> (https://godbolt.org/z/3E49c4oT7) and not necessarily easy to understand
>>>> (immagine if s is part of a class hierarchy or a member of another
>>>> class...)
>>>> q
>>>> An improvement for the end-user is to delete the copy-constructor of s
>>>> by hand, it does not change what programs are valid, but the error
>>>> message is much more easy to understand.
>>>>
>>>> But it does not fix the underlying issue, and the fact that one cannot
>>>> simply follow the "rule of 0" and let the compiler use the defaulted
>>>> copy and move constructors without writing them down.
>>>>
>>>> Does anyone know if there is already a paper trying to fix this issue,
>>>> or if there was one and was rejected?
>>>> I assume the main difficulty is specifying something that also works
>>>> with forward-declared types.
>>>>
>>>> Thanks
>>>>
>>>> Federico
>>>>
>>>
>>> You can't have cake and eat it too, "fix" would need to ban
>>> use of forward declared types in vector:
>>> ```
>>> struct Foo
>>> {
>>> std::vector<Foo> f;
>>> };
>>> ```
>>> Now this works fine, after it would not.
>>
>> Wouldn't it be possible to have vector play well with is_copy_assignable
>> (ie delete copy-constructor if contained type is not copyable) if the
>> type is not forward-declared?
>>
>> Granted, is_copy_assignable could still be wrong with forward-declared
>> types, but it would at least work correctly for more use-cases.
>
> This will fix nothing, as the vector needs to behave the same
> whether the type is forward declared or not. You do not control it
> as in some TU it will use forward declared type and in others it will not.
> You will get multiple ODR problems where you check this condition.
I am not sure I get your point.
The behavior of vector would not change, as "auto s2 = s1;" would
continue not to compile.
Received on 2023-06-13 15:20:01