Подтвердите эту стандартную ошибку библиотеки, связанную с распределителями в MSVC 2015 RC

Вот SSCCE:

#include <memory>
#include <vector>

template <class T> struct my_allocator : std::allocator<T> {
    //This overriding struct causes the error
    template <class U> struct rebind {
        typedef my_allocator<T> other;
    };

    //Ignore all this.
    typedef std::allocator<T> base;
    typename base::pointer allocate(typename base::size_type n, std::allocator<void>::const_pointer /*hint*/=nullptr) { return (T*)malloc(sizeof(T)*n); }
    void deallocate(typename base::pointer p, typename base::size_type /*n*/) { free(p); }
};

int main(int /*argc*/, char* /*argv*/[]) {
    std::vector<int,my_allocator<int>> vec;
    return 0;
}

GCC нравится.
ICC нравится.
Clang нравится.
Даже MSVC 2013 нравится.
Но MSVC 2015 RC выплевывает:

1>------ Build started: Project: Test Alloc, Configuration: Debug Win32 ------
1>  main.cpp
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(579): error C2664: 'void std::_Wrap_alloc<my_allocator<int>>::deallocate(int *,unsigned int)': cannot convert argument 1 from 'std::_Container_proxy *' to 'int *'
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(579): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(574): note: while compiling class template member function 'void std::_Vector_alloc<std::_Vec_base_types<_Ty,_Alloc>>::_Free_proxy(void)'
1>          with
1>          [
1>              _Ty=int,
1>              _Alloc=my_allocator<int>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(541): note: see reference to function template instantiation 'void std::_Vector_alloc<std::_Vec_base_types<_Ty,_Alloc>>::_Free_proxy(void)' being compiled
1>          with
1>          [
1>              _Ty=int,
1>              _Alloc=my_allocator<int>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(668): note: see reference to class template instantiation 'std::_Vector_alloc<std::_Vec_base_types<_Ty,_Alloc>>' being compiled
1>          with
1>          [
1>              _Ty=int,
1>              _Alloc=my_allocator<int>
1>          ]
1>  c:\users\ian mallett\desktop\test-alloc\main.cpp(18): note: see reference to class template instantiation 'std::vector<int,my_allocator<int>>' being compiled

Родственная программа выдает аналогичные фишинговые ошибки звучания. Вот два:
ошибка C2664: 'void std :: _ Wrap_alloc> :: deallocate (int *, unsigned int)': невозможно преобразовать аргумент 1 из 'std :: _ Container_proxy *' в 'int *'
невозможно преобразовать аргумент 1 из 'std :: _ Wrap_alloc>' в 'const align_allocator &'

Логический вопрос: это ошибка? Если это так, я буду (попробуйте), чтобы отправить его.

[РЕДАКТИРОВАТЬ: как указано в комментариях, это происходит только в режиме отладки. В режиме выпуска он компилируется и работает нормально.] [РЕДАКТИРОВАТЬ: гораздо более простой пример]


person imallett    schedule 19.07.2015    source источник
comment
Возможно, это не имеет значения, но добавление объявлений в пространство имен std - это UB.   -  person cpplearner    schedule 19.07.2015
comment
@cpplearner Это неправда. Есть исключения, см. Расширение пространства имен std.   -  person Captain Obvlious    schedule 19.07.2015
comment
@CaptainObvlious Я не думаю, что здесь применимы какие-либо из этих исключений.   -  person cpplearner    schedule 19.07.2015
comment
Что делать, если вы отключите диагностический режим стандартной библиотеки MSVC?   -  person Ulrich Eckhardt    schedule 19.07.2015
comment
Я отредактировал вопрос, чтобы не помещать код в std::; ошибка все еще возникает. @UlrichEckhardt, запущенный в режиме выпуска, приводит к его успешной компиляции / запуску.   -  person imallett    schedule 19.07.2015
comment
Это просто ошибочный код, вы не поддерживаете повторную привязку. Множество мест, где вы можете узнать, как создать свой собственный тип распределителя, ничего, что никогда не должно было бы повторяться здесь :)   -  person Hans Passant    schedule 19.07.2015
comment
Я предполагаю, что диагностический режим оборачивает ваш распределитель для предотвращения злоупотреблений. Если предположить, что @Hans Passant прав (честно говоря, у меня нет опыта реализации распределителей в стиле STL), для этого может потребоваться работающая реализация rebind() в вашем распределителе, которая объяснила бы такое поведение и действительно сделала бы ошибку в вашем коде. Пробовали ли вы режим диагностики для других стандартных библиотек (#define _GLIBCXX_DEBUG)?   -  person Ulrich Eckhardt    schedule 19.07.2015


Ответы (1)


Логический вопрос: это ошибка?

false.


Хотя ошибка шаблона, представленная здесь MSVC, чрезвычайно бесполезна, это моя ошибка (обнадеживающая, поскольку эта версия стандартной библиотеки поставляется сегодня).

Я создал этот распределитель (а позже и сокращенный тестовый пример) из множества источников, поэтому решил, что он правильный. Однако, как было предложено в комментариях, я снова проверил, на этот раз полностью по документации.

Отсутствующий компонент здесь - это один из конструкторов копирования (шаблонный, который не может быть автоматически сгенерирован). Это появляется только тогда, когда структура rebind определена, поскольку структура rebind переопределяет ту же структуру в родительском классе (что, поскольку она находится в родительском классе, в конечном итоге вызывает вызов конструктора копирования родительского, поэтому нет никаких проблем (кроме того, что это технически неправильно)).


Интересно то, что до сих пор ошибки не было. Как я уже сказал, GCC, Clang и MSVC 2013 нравятся всем (даже с их соответствующими режимами отладки). Просто ни один из этих не произошло вызова конструктора копирования шаблона. Тем не менее, это указано в стандарте, так что, опять же, это моя ошибка.

Поздравляем команду компиляторов MSVC и извиняемся за шум! : D

person imallett    schedule 20.07.2015
comment
Спасибо за четкий ответ, я столкнулся с той же проблемой, и вы, вероятно, сэкономили мне несколько часов! - person Benlitz; 26.12.2018