I have the following snippet of code:
#include <algorithm>
#include <memory>
#include <vector>
// Example allocator, doesn't do anything but implements std::allocator_traits
template<typename T>
struct null_allocator {
using value_type = T;
using size_type = std::size_t;
using pointer = T *;
using const_pointer = const pointer;
//using difference_type = typename std::pointer_traits<pointer>::difference_type;
using reference = T &;
using const_reference = const T &;
null_allocator() {}
template<typename U>
null_allocator(const null_allocator<U>&) {}
T* allocate(std::size_t size) {
(void) size;
return nullptr;
}
void deallocate(T* ptr, std::size_t size) {
(void) ptr;
(void) size;
}
template<typename U>
struct rebind
{
typedef null_allocator<U> other;
};
};
int main(int argc, char** argv) {
std::vector<void*, null_allocator<void*>> vec;
void * args;
vec.push_back(args);
vec.erase(vec.begin());
}
gcc.godbolt.org shows that it compiles with Clang: http://goo.gl/VhKLCe
I pass a custom allocator to a std::vector, push a single object onto the vector, and try to call std::erase on that vector. The custom allocator is a null allocator that does nothing and is unimportant. The point is that this snippet compiles fine on Linux with both GCC and Clang, but fails to compile on OSX with Xcode/Apple Clang.
The output of clang --version is Apple LLVM version 7.0.0 (clang-700.1.76).
It appears that the compiler cannot complete std::iterator_traits:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:604:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/iterator:1120:54: error: no type named 'iterator_category' in
'std::__1::iterator_traits<void **const>'
typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
bug.cpp:42:13: note: in instantiation of template class 'std::__1::__wrap_iter<void **const>' requested here
vec.erase(vec.begin());
^
In file included from bug.cpp:1:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:604:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/iterator:1121:54: error: no type named 'value_type' in
'std::__1::iterator_traits<void **const>'
typedef typename iterator_traits<iterator_type>::value_type value_type;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/iterator:1122:54: error: no type named 'difference_type' in
'std::__1::iterator_traits<void **const>'
typedef typename iterator_traits<iterator_type>::difference_type difference_type;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/iterator:1123:54: error: no type named 'pointer' in
'std::__1::iterator_traits<void **const>'
typedef typename iterator_traits<iterator_type>::pointer pointer;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/iterator:1124:54: error: no type named 'reference' in
'std::__1::iterator_traits<void **const>'
typedef typename iterator_traits<iterator_type>::reference reference;
Does anyone know a good workaround for this issue?
Aucun commentaire:
Enregistrer un commentaire