Вот 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 &’
Булевый вопрос: это ошибка? Если это так, я буду (пытаться) представить его.
[РЕДАКТИРОВАТЬ: как отмечено в комментариях, это только происходит в режиме отладки. В режиме выпуска он компилируется и выполняется нормально.] [РЕДАКТИРОВАТЬ: гораздо более простой пример]Булевый вопрос: это ошибка?
false
,
Несмотря на то, что ошибка шаблона, представленная MSVC, здесь совершенно бесполезна, эта ошибка моя (обнадеживает, поскольку эта версия стандартной библиотеки поставляется сегодня).
Я создал этот распределитель (а позже и сокращенный контрольный пример) из различных источников, поэтому я предположил, что он был правильным. Однако, как предлагается в комментариях, я снова проверил, на этот раз исчерпывающе по отношению к документации.
Отсутствующий здесь компонент является одним из конструкторов копирования (шаблонный, который не может быть сгенерирован автоматически). Это появляется только тогда, когда rebind
структура определяется, так как rebind
struct переопределяет ту же структуру в родительском классе (который, поскольку он находится в родительском классе, в конечном итоге вызывает родители вызвать конструктор копирования, так что проблем нет (за исключением того, что это технически неправильно)).
Интересно, что ошибка не возникала до сих пор. Как я уже сказал, GCC, Clang и MSVC 2013 всем нравятся (даже с соответствующими режимами отладки). Просто ни один из них получилось вызвать конструктор копирования шаблона. Тем не менее, это является определяется стандартом, так что опять же, ошибка в конечном итоге моя.
Поздравляем команду компилятора MSVC, и извините за шум! : D