如何解决 std::allocator 的弃用问题?

How to fix this deprecated use of std::allocator?

这里是关键点:

1:该项目使用开源存储库NanoRT作为项目中的光线追踪器。

2:本项目编译于Visual Studio 2019 (C++17)

3:此项目编译时将警告视为错误(并且无法更改)。添加定义以抑制这些警告没有帮助。

但是,看起来这段代码的一部分在 C++17 中不起作用,因为它使用了一些已被弃用的东西:(我提供的 link 中的第 133 和 134 行)

  typedef typename std::allocator<T>::pointer pointer;
  typedef typename std::allocator<T>::size_type size_type;

我需要弄清楚如何解决这个问题。该错误建议使用 std::allocator_traits 但我真的不熟悉 std::allocatorallocator_traits.

的这种用法

查看源代码,这是几行修复,还是比这复杂得多并且需要重构大部分代码?

看起来 pointer 被用作 allocate() 的 return 和 deallocate() 的第一个参数,size_type 被用在相同的地方

  // Actually do the allocation. Use the stack buffer if nobody has used it yet
  // and the size requested fits. Otherwise, fall through to the standard
  // allocator.
  pointer allocate(size_type n, void *hint = 0) {
    if (source_ != NULL && !source_->used_stack_buffer_ &&
        n <= stack_capacity) {
      source_->used_stack_buffer_ = true;
      return source_->stack_buffer();
    } else {
      return std::allocator<T>::allocate(n, hint);
    }
  }

  // Free: when trying to free the stack buffer, just mark it as free. For
  // non-stack-buffer pointers, just fall though to the standard allocator.
  void deallocate(pointer p, size_type n) {
    if (source_ != NULL && p == source_->stack_buffer())
      source_->used_stack_buffer_ = false;
    else
      std::allocator<T>::deallocate(p, n);
  }

std::allocator<T>::pointer 替换为 T*,将 std::allocator<T>::size_type 替换为 std::size_t。这就是那些已弃用的成员类型别名的定义。

is this a few-line fix, or is this much more complicated than that and would require restructuring large portions of the code?

这似乎是一个微不足道的变化。

The error suggests using std::allocator_traits

如果分配器类型是模板化的,则应使用

std::allocator_traits。这似乎不是这里的情况,因此使用 std::allocator_traits 是不必要的。

但是如果我们要解决分配器模板化的问题:假设模板参数是 Alloc。那么你应该用std::allocator_traits<Alloc>::pointer替换Alloc::pointer,用std::allocator_traits<Alloc>::size_type替换Alloc::size_type

However, it looks like part of this code does not work in C++17, as it uses something that has become deprecated

实际上,使用已弃用的功能仍然有效。但它仍应得到修复,因为它将在 C++20 中停止工作。 std::allocator<T>::pointer 已在 C++20 中删除。

有几种方法可以解决这个问题,但一种尺寸并不适合所有人。

最简单的路径:

对于std::allocator<T>,类型std::size_t始终与size_type相同,类型T*始终与pointer相同。所以最简单的事情就是在这些类型中进行子。

std::allocator_traits路径:

这些类型也作为 std::allocator_traits<std::allocator<T>> 类型的嵌套类型存在。所以你可以像这样访问它们:

std::allocator_traits<std::allocator<T>>::pointer

创建类型别名以减少冗长是很常见的:

using pointer = std::allocator_traits<std::allocator<T>>::pointer;

讽刺:allocator<T>::size_type 在 C++20 中被“弃用”。