Apple Clang:无法使用自定义分配器编译调用std :: erase for vector

时间:2015-10-28 21:27:00

标签: c++ macos c++11 clang allocator

我有以下代码片段:

#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显示它与Clang编译:http://goo.gl/VhKLCe

我将自定义分配器传递给std :: vector,将单个对象推送到向量上,并尝试在该向量上调用std :: erase。自定义分配器是一个空分配器,它不执行任何操作并且不重要。关键是这个片段在Linux上用GCC和Clang编译得很好,但是无法在OSX上用Xcode / Apple Clang编译。

clang --version的输出是Apple LLVM版本7.0.0(clang-700.1.76)。

似乎编译器无法完成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;

有没有人知道这个问题的好方法?

1 个答案:

答案 0 :(得分:1)

我不知道为什么会这样,但如果你将自定义分配器中的using const_pointer = const pointer;更改为using const_pointer = const T *;,它似乎对我有效(即使在OS X上使用Apple的Clang)。