[Bug libstdc++/84601] New: std::optional<std::pair<int, int>> is not assignment copyable
romain.geissler at amadeus dot com
gcc-bugzilla@gcc.gnu.org
Tue Feb 27 18:23:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84601
Bug ID: 84601
Summary: std::optional<std::pair<int, int>> is not assignment
copyable
Product: gcc
Version: 8.0.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: romain.geissler at amadeus dot com
Target Milestone: ---
Hi,
I am having trouble with this simple code snippet:
<<EOF
#include <optional>
using pair_t = std::pair<int, int>;
using opt_t = std::optional<pair_t>;
static_assert(std::is_copy_constructible_v<opt_t::value_type>);
static_assert(std::is_copy_assignable_v<opt_t::value_type>);
static_assert(std::is_copy_assignable_v<opt_t>); // assertion fails.
class A
{
void f(const opt_t& opt)
{
_opt = opt; // compilation failure here.
}
opt_t _opt;
};
EOF
Compiled with: -std=gnu++17
gcc 8 says:
<<GCC_ERROR
file.cpp:9:15: error: static assertion failed
static_assert(std::is_copy_assignable_v<opt_t>); // assertion fails.
^~~
file.cpp: In member function ‘void A::f(const opt_t&)’:
file.cpp:15:16: error: use of deleted function ‘std::optional<std::pair<int,
int> >& std::optional<std::pair<int, int> >::operator=(const
std::optional<std::pair<int, int> >&)’
_opt = opt; // compilation failure here.
^~~
In file included from file.cpp:1:
/remote/tools/Linux/2.6/1A/toolchain/x86_64-2.6.32-v4.0.14/include/c++/8.0.1/optional:612:11:
note: ‘std::optional<std::pair<int, int> >& std::optional<std::pair<int, int>
>::operat
or=(const std::optional<std::pair<int, int> >&)’ is implicitly deleted because
the default definition would be ill-formed:
class optional
^~~~~~~~
/remote/tools/Linux/2.6/1A/toolchain/x86_64-2.6.32-v4.0.14/include/c++/8.0.1/optional:612:11:
error: use of deleted function ‘std::_Optional_base<_Tp, true, true>&
std::_Optional_ba
se<_Tp, true, true>::operator=(const std::_Optional_base<_Tp, true, true>&)
[with _Tp = std::pair<int, int>]’
/remote/tools/Linux/2.6/1A/toolchain/x86_64-2.6.32-v4.0.14/include/c++/8.0.1/optional:560:23:
note: ‘std::_Optional_base<_Tp, true, true>& std::_Optional_base<_Tp, true,
true>::oper
ator=(const std::_Optional_base<_Tp, true, true>&) [with _Tp = std::pair<int,
int>]’ is implicitly deleted because the default definition would be
ill-formed:
_Optional_base& operator=(const _Optional_base&) = default;
^~~~~~~~
/remote/tools/Linux/2.6/1A/toolchain/x86_64-2.6.32-v4.0.14/include/c++/8.0.1/optional:560:23:
error: use of deleted function ‘std::_Optional_payload<std::pair<int, int>,
true>& std:
:_Optional_payload<std::pair<int, int>, true>::operator=(const
std::_Optional_payload<std::pair<int, int>, true>&)’
/remote/tools/Linux/2.6/1A/toolchain/x86_64-2.6.32-v4.0.14/include/c++/8.0.1/optional:105:12:
note: ‘std::_Optional_payload<std::pair<int, int>, true>&
std::_Optional_payload<std::p
air<int, int>, true>::operator=(const std::_Optional_payload<std::pair<int,
int>, true>&)’ is implicitly deleted because the default definition would be
ill-formed:
struct _Optional_payload
^~~~~~~~~~~~~~~~~
/remote/tools/Linux/2.6/1A/toolchain/x86_64-2.6.32-v4.0.14/include/c++/8.0.1/optional:159:24:
error: union member ‘std::_Optional_payload<std::pair<int, int>,
true>::<unnamed union>
::_M_payload’ with non-trivial ‘std::pair<_T1, _T2>& std::pair<_T1,
_T2>::operator=(typename
std::conditional<std::__and_<std::is_copy_assignable<_Tp>,
std::is_copy_assignable<_T2>
>::value, const std::pair<_T1, _T2>&, const std::__nonesuch_no_braces&>::type) [with _T1 = int; _T2 = int; typename std::conditional<std::__and_<std::is_copy_assignable<_Tp>, std::i
s_copy_assignable<_T2> >::value, const std::pair<_T1, _T2>&, const
std::__nonesuch_no_braces&>::type = const std::pair<int, int>&]’
_Stored_type _M_payload;
^~~~~~~~~~
GCC_ERROR
Clang 6 fails with similar reason (non trivial copy assignment operator on
union member):
<<CLANG_ERROR
file.cpp:9:1: error: static_assert failed due to requirement
'std::is_copy_assignable_v<opt_t>'
static_assert(std::is_copy_assignable_v<opt_t>); // assertion fails.
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
file.cpp:15:14: error: object of type 'std::optional<std::pair<int, int> >'
cannot be assigned because its copy assignment operator is implicitly deleted
_opt = opt; // compilation failure here.
^
/opt/1A/toolchain/x86_64-2.6.32-v4.0.14/lib64/gcc/x86_64-1a-linux-gnu/8.0.1/../../../../include/c++/8.0.1/optional:613:7:
note: copy assignment operator of 'optional<std::pair<int,
int> >' is implicitly deleted because base class '_Optional_base<std::pair<int,
int> >' has a deleted copy assignment operator
: private _Optional_base<_Tp>,
^
/opt/1A/toolchain/x86_64-2.6.32-v4.0.14/lib64/gcc/x86_64-1a-linux-gnu/8.0.1/../../../../include/c++/8.0.1/optional:560:23:
note: explicitly defaulted function was implicitly deleted
here
_Optional_base& operator=(const _Optional_base&) = default;
^
/opt/1A/toolchain/x86_64-2.6.32-v4.0.14/lib64/gcc/x86_64-1a-linux-gnu/8.0.1/../../../../include/c++/8.0.1/optional:584:30:
note: copy assignment operator of '_Optional_base<std::pai
r<int, int>, true, true>' is implicitly deleted because field '_M_payload' has
a deleted copy assignment operator
_Optional_payload<_Tp> _M_payload;
^
/opt/1A/toolchain/x86_64-2.6.32-v4.0.14/lib64/gcc/x86_64-1a-linux-gnu/8.0.1/../../../../include/c++/8.0.1/optional:159:24:
note: copy assignment operator of '_Optional_payload<std::
pair<int, int>, true>' is implicitly deleted because variant field '_M_payload'
has a non-trivial copy assignment operator
_Stored_type _M_payload;
^
CLANG_ERROR
Unless I missed something from the std::optional specification, we should be
able to use std::optional with std::pair's of integral types. Is this error
actually expected ?
Note: with the implementation from gcc 7 (and libstdc++ shipping with it), this
snippet was accepted (and clang 5 + libstdc++ from gcc 7 was also accepting
it).
Cheers,
Romain
More information about the Gcc-bugs
mailing list