[PATCH] libstdc++/77641 fix std::variant for literal types

Ville Voutilainen ville.voutilainen@gmail.com
Thu Sep 22 06:45:00 GMT 2016


This problem is not introduced by the latest patch, but it's something that
we should look at anyway. There's been recent discussion about what
assignments do with variants that hold references. Consider this:

#include <variant>

int main()
{
   float f1 = 1.0f, f2 = 2.0f;

   std::variant<float&> v1(f1);

   v1 = f2; // #1
}

The line marked with #1 fails to compile before and after the latest
variant patch:

In file included from tony-variant1.cpp:1:0:
/usr/local/include/c++/7.0.0/variant: In instantiation of
‘std::enable_if_t<(((__exactly_once<typename
std::variant<_Types>::__to_type_impl<__accepted_index<_Tp&&>,
(__accepted_index<_Tp&&> < sizeof... (_Types))>::type> &&
is_constructible_v<typename
std::variant<_Types>::__to_type_impl<__accepted_index<_Tp&&>,
(__accepted_index<_Tp&&> < sizeof... (_Types))>::type, _Tp&&>) &&
is_assignable_v<typename
std::variant<_Types>::__to_type_impl<__accepted_index<_Tp&&>,
(__accepted_index<_Tp&&> < sizeof... (_Types))>::type&, _Tp&&>) && (!
is_same_v<typename std::decay<_Tp>::type, std::variant<_Types> >)),
std::variant<_Types>&> std::variant<_Types>::operator=(_Tp&&) [with
_Tp = float&; _Types = {float&};
std::enable_if_t<(((__exactly_once<typename
std::variant<_Types>::__to_type_impl<__accepted_index<_Tp&&>,
(__accepted_index<_Tp&&> < sizeof... (_Types))>::type> &&
is_constructible_v<typename
std::variant<_Types>::__to_type_impl<__accepted_index<_Tp&&>,
(__accepted_index<_Tp&&> < sizeof... (_Types))>::type, _Tp&&>) &&
is_assignable_v<typename
std::variant<_Types>::__to_type_impl<__accepted_index<_Tp&&>,
(__accepted_index<_Tp&&> < sizeof... (_Types))>::type&, _Tp&&>) && (!
is_same_v<typename std::decay<_Tp>::type, std::variant<_Types> >)),
std::variant<_Types>&> = std::variant<float&>&]’:
tony-variant1.cpp:9:9:   required from here
/usr/local/include/c++/7.0.0/variant:1151:8: error: use of deleted
function ‘std::__detail::__variant::_Reference_storage<float&>&
std::__detail::__variant::_Reference_storage<float&>::operator=(std::__detail::__variant::_Reference_storage<float&>&&)’
      *static_cast<__storage<__to_type<__index>>*>(this->_M_storage())
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        = forward<_Tp>(__rhs);
        ^~~~~~~~~~~~~~~~~~~~~
In file included from tony-variant1.cpp:1:0:
/usr/local/include/c++/7.0.0/variant:137:12: note:
‘std::__detail::__variant::_Reference_storage<float&>&
std::__detail::__variant::_Reference_storage<float&>::operator=(std::__detail::__variant::_Reference_storage<float&>&&)’
is implicitly deleted because the default definition would be
ill-formed:
     struct _Reference_storage
            ^~~~~~~~~~~~~~~~~~
/usr/local/include/c++/7.0.0/variant:137:12: error: non-static
reference member ‘float&
std::__detail::__variant::_Reference_storage<float&>::_M_storage’,
can’t use default assignment operator



More information about the Libstdc++ mailing list