Рассмотрим следующий фиктивный распределитель (созданный для примера):
template<typename T> class C
{
public:
typedef T value_type;
C() = default;
template<typename U>
C(C<U> const &a)
{}
T* allocate(std::size_t n, T const* = nullptr)
{
return new T[n];
}
void deallocate(T* p, std::size_t n)
{
return;
}
typedef value_type *pointer;
typedef const value_type *const_pointer;
typedef value_type & reference;
typedef value_type const &const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
static pointer address(reference x) { return &x; }
static const_pointer address(const_reference x) { return &x; }
static size_type max_size() { return std::numeric_limits<size_type>::max(); }
template <typename U> static void destroy(U* ptr) { ptr->~U(); }
template <typename U> struct rebind { using other = C<U>; };
template<typename U, typename... Args>
static void construct(U* ptr, Args&&... args) {
new (ptr) U(std::forward<Args>(args)...);
}
};
template<class T1, class T2>
bool operator==(C<T1> const& lhs, C<T2> const& rhs)
{
return std::addressof(lhs) == std::addressof(rhs);
}
template<class T1, class T2>
bool operator!=(C<T1> const& lhs, C<T2> const& rhs)
{
return !(lhs == rhs);
}
Большая часть этого кода является котельной.Важным моментом является то, что любые два экземпляра распределителя будут считаться несовместимыми - bool operator==
всегда возвращает false
.Когда я пытаюсь использовать этот распределитель с большинством контейнеров STL, таких как std::vector
, для копирования-назначения очень простых элементов, таких как:
std::vector<int, C<int>> a;
a = std::vector<int, C<int>>();
Все работает, и я получаю ожидаемое поведение.Однако, когда я делаю то же самое, но вместо этого std::unordered_map
, я получаю разное поведение на двух платформах, которые мне нужно поддерживать.В Linux с GCC 7.1 я продолжаю получать ожидаемое поведение.Однако в Windows с VS 2015 я получаю сообщение об ошибке, утверждающее containers incompatible for swap
в заголовке VS под названием xmemory0
.Обратите внимание, что код, используемый для std::unordered_map
, в значительной степени совпадает с приведенным выше для std::vector
:
using B = std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, C<std::pair<int const, int>>>;
B b;
b = B();
Что-то не так с моим распределителем, и GCC 7.1 дает мне неопределенное поведение?Если нет, то это сбой библиотеки времени выполнения VS 2015?Если так, то почему эта ошибка присутствует только с unordered_map
?