简体   繁体   English

Apple Clang:无法使用自定义分配器编译对 std::erase 向量的调用

[英]Apple Clang: can't compile call to std::erase for vector with custom allocator

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 gcc.godbolt.org 显示它使用 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.我将自定义分配器传递给 std::vector,将单个对象推送到向量上,并尝试对该向量调用 std::erase。 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.关键是这个片段在 Linux 上使用 GCC 和 Clang 编译得很好,但在使用 Xcode/Apple Clang 的 OSX 上编译失败。

The output of clang --version is Apple LLVM version 7.0.0 (clang-700.1.76). clang --version 的输出是 Apple LLVM 版本 7.0.0 (clang-700.1.76)。

It appears that the compiler cannot complete std::iterator_traits:似乎编译器无法完成 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?有没有人知道解决这个问题的好方法?

I don't know why this works, but if you change using const_pointer = const pointer;我不知道为什么会这样,但是如果您using const_pointer = const pointer;更改in your custom allocator to using const_pointer = const T *;在您的自定义分配器中using const_pointer = const T *; it seems to work for me (even on OS X using Apple's Clang).它似乎对我有用(即使在使用 Apple 的 Clang 的 OS X 上)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM