Почему std :: vector требует is_trivial для побитового перемещения, а не просто is_trivially_copyable? - PullRequest
4 голосов
/ 11 января 2020

Я вижу этот код в libstdc ++ stl_uninitialized.h:

  // This class may be specialized for specific types.
  // Also known as is_trivially_relocatable.
  template<typename _Tp, typename = void>
    struct __is_bitwise_relocatable
    : is_trivial<_Tp> { };

  template <typename _Tp, typename _Up>
    inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*>
    __relocate_a_1(_Tp* __first, _Tp* __last,
           _Tp* __result, allocator<_Up>&) noexcept
    {
      ptrdiff_t __count = __last - __first;
      if (__count > 0)
    __builtin_memmove(__result, __first, __count * sizeof(_Tp));
      return __result + __count;
    }

Но мне кажется, что memmove подойдет для объектов, которые легко копируются, даже если они не являются тривиальными по умолчанию. Кого волнует конструктор по умолчанию в этом случае?

1 Ответ

3 голосов
/ 16 января 2020

Я спросил об этом в ветке bugzilla, и они указали мне на { ссылка }. По сути, memcpy недостаточно для запуска времени жизни объекта, если конструктор по умолчанию также не является тривиальным. Таким образом, технически это может быть нормально с точки зрения количества битов в памяти, но будет неопределенным поведением в соответствии со стандартом. Поскольку этот код библиотеки написан командой компиляторов, они имеют право сделать это в любом случае, если они думают, что это безопасно, но они, очевидно, не убеждены в безопасности.

...