【问题标题】:C++: Can't propagate polymorphic_allocator with scoped_allocator_adaptorC++:不能用 scoped_allocator_adaptor 传播 polymorphic_allocator
【发布时间】:2019-02-12 16:29:19
【问题描述】:

我有一个vector<vector<int>>,并希望从memory_resource 中获取整个内存(即外部和内部向量)。这是一个精简的例子,首先是无聊的部分:

#include <boost/container/pmr/memory_resource.hpp>
#include <boost/container/scoped_allocator.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
#include <iostream>
#include <string>
#include <vector>

// Sample memory resource that prints debug information
class MemoryResource : public boost::container::pmr::memory_resource {
  void* do_allocate(std::size_t bytes, std::size_t alignment) {
    std::cout << "Allocate " << bytes << " bytes" << std::endl;
    return malloc(bytes);
  }
  void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) { free(p); }
  bool do_is_equal(const memory_resource& other) const noexcept { return true; }
};

这是我感兴趣的部分:

template <typename T>
using Alloc = boost::container::pmr::polymorphic_allocator<T>;
// using Alloc = std::allocator<T>;

template <typename T>
using PmrVector = std::vector<T, boost::container::scoped_allocator_adaptor<Alloc<T>>>;

using Inner = PmrVector<int>;

int main() {
  MemoryResource resource{};

  PmrVector<Inner> v(1000, Alloc<Inner>{&resource});
  // PmrVector<Inner> v(1337, Alloc<Inner>{});
  v[0].resize(100);
}

这给了我一个lengthy compiler warning,本质上是说它找不到内部向量的构造函数。

如果我使用常规分配器而不是多态分配器(例如,std::allocator - 请参阅注释掉的行),一切似乎都正常。

gcc的报错信息比clang的好一点:

/usr/local/include/boost/container/allocator_traits.hpp:415:10:
error: no matching function for call to '
  std::vector<int, polymorphic_allocator<int> >::vector(
    scoped_allocator_adaptor<...>&, polymorphic_allocator<...>&
  )
'

为什么 boost 会尝试通过两次传递分配器来构造向量?

另外,here 是一个使用 STL(实验性)而不是 boost 的版本。那个给出了一个实际的错误消息“如果 uses_allocator 为真,则必须可以使用分配器进行构造”,但这对我也没有帮助。

也许我在概念上理解错误。这是这样做的方法还是有更好的方法来解决原始问题?

【问题讨论】:

    标签: c++ boost c++17 allocator c++pmr


    【解决方案1】:

    啊。解释隐藏在std::experimental::pmr::polymorphic_allocator::construct

    这个函数被任何人调用(通过std::allocator_traits) 分配器感知对象,例如 std::vector,被赋予了 std::polymorphic_allocator 作为要使用的分配器。自从 memory_resource* 隐式转换为 polymorphic_allocator,即 内存资源指针将传播到任何分配器感知 使用多态分配器的子对象。

    事实证明,多态分配器会自动传播。这也解释了为什么分配器在 gcc 错误消息中被传递了两次。

    这是一个工作版本:

    template <typename T>
    using Alloc = std::experimental::pmr::polymorphic_allocator<T>;
    
    template <typename T>
    using PmrVector = std::vector<T, Alloc<T>>;
    
    using Inner = PmrVector<int>;
    
    int main() {
      MemoryResource resource{};
    
      PmrVector<Inner> v(1000, Alloc<Inner>{&resource});
      v[0].resize(100);
    }
    

    这是几个小时前我需要的信息:

    如何同时使用 polymorphic_allocator 和 scoped_allocator_adaptor?

    你没有。确保所有内部容器也使用多态分配器,然后内存资源将自动传递。

    【讨论】:

    • 非常酷。感谢您分享此分析。节省了我得出相同结论的时间
    猜你喜欢
    • 2017-12-18
    • 2015-12-18
    • 1970-01-01
    • 2014-04-04
    • 1970-01-01
    • 2013-05-18
    • 2018-08-10
    • 2016-10-26
    • 2019-12-17
    相关资源
    最近更新 更多