gpt4 book ai didi

c++ - 什么是 C++ 中的 "uses allocator"和 "scoped allocator"结构

转载 作者:行者123 更新时间:2023-12-05 03:24:21 26 4
gpt4 key购买 nike

有相当多的few questions就这里面说说uses allocatorscoped allocator但它们来自于知道这些是什么以及它们的用途的假设。

通常的 C++ 引用资料中的解释解释了是什么,而不是如何或为什么。

该网站缺少一个规范的答案,可以为不熟悉该主题的人提供背景知识。

最佳答案

它是一种允许泛型容器类型(广义上的容器类型)检测泛型类型参数何时期望与分配器一起使用的协议(protocol)。

然后他们可以决定通过自动将外部分配器传播到内部类型来支持它。典型的例子是当你想要一个 std::map<std::vector<std::string>, std::set<int> >全部使用相同的分配器系列。

包含嵌套 allocator_type 的类型typename 将自动检测为 uses_allocator类型,包括所有标准容器。

典型的其他uses_allocator标准库中的类型是 std::pairstd::tuple ,还有函数包装器类型( std::functionstd::packaged_type )和容器适配器( std::stack 和 friend )。

作用域分配器允许调整外部分配器或外部分配器和一组内部分配器(如果它们不相同),通知作用域分配器感知容器分配器类型用于内部“使用分配器”类型。

来自 scoped_allocator_adaptor 的提升文档:

This class is a C++03-compatible implementation of std::scoped_allocator_adaptor.The class template scoped_allocator_adaptor is an allocator template that specifiesthe memory resource (the outer allocator) to be used by a container (as any otherallocator does) and also specifies an inner allocator resource to be passed tothe constructor of every element within the container.

This adaptor is instantiated with one outer and zero or more inner allocatortypes. If instantiated with only one allocator type, the inner allocatorbecomes the scoped_allocator_adaptor itself, thus using the same allocatorresource for the container and every element within the container and, if theelements themselves are containers, each of their elements recursively.

If instantiated with more than one allocator, the first allocator is theouter allocator for use by the container, the second allocator is passed tothe constructors of the container's elements, and, if the elements themselvesare containers, the third allocator is passed to the elements' elements, andso on. If containers are nested to a depth greater than the number ofallocators, the last allocator is used repeatedly, as in the single-allocatorcase, for any remaining recursions.

根据我的经验,Boost Container 始终比大多数标准库实现更好地支持此协议(protocol),但我承认我多年来没有检查过它们的状态。

我刚刚为您提供了使用 scoped_allocator_adaptor 的示例在这个答案中:Does boost interprocess support sharing objects containing pointers between processes? .在那张照片中,Shared::Bar是内部“uses-allocator”类型的示例,它通知容器 ( vector ) 在构造元素时传递其分配器的(转换后的)拷贝。

我在此处复制该答案的代码 list ,以确保示例引用不会过时:

Live On Coliru

#include <boost/container/scoped_allocator.hpp>
#include <boost/container/string.hpp>
#include <boost/container/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <string>
namespace bip = boost::interprocess;

namespace Shared {
#ifdef COLIRU
using Segment = bip::managed_mapped_file;
#else
using Segment = bip::managed_shared_memory;
#endif
using Mgr = Segment::segment_manager;

template <typename T>
using Alloc = boost::container::scoped_allocator_adaptor< //
bip::allocator<T, Mgr>>;

template <typename T> using Vector = std::vector<T, Alloc<T>>;

using String = boost::container::basic_string< //
char, std::char_traits<char>, Alloc<char>>;

struct Bar {
using allocator_type = Alloc<char>;
String first_name, last_name;

template <typename Alloc>
Bar(std::allocator_arg_t, Alloc alloc) : first_name(alloc)
, last_name(alloc) {}

template <typename Alloc>
Bar(Alloc&& alloc) : first_name(alloc)
, last_name(alloc) {}

Bar(Bar const&) = default;
template <typename Alloc>
Bar(Bar const& rhs, Alloc alloc) : first_name(rhs.first_name, alloc), last_name(rhs.last_name, alloc) {}

Bar& operator=(Bar const&) = default;

template <typename Alloc> Bar(std::string_view first_name, std::string_view last_name, Alloc alloc) :
first_name(first_name, alloc), last_name(last_name, alloc) {}
};

struct Snafu {
std::array<int, 5> no_problem;
};

struct Foo {
Vector<Bar> bars;
Vector<Snafu> snafus;

template <typename Alloc> //
Foo(Alloc alloc) : bars(alloc)
, snafus(alloc) {}
};
}

#include <iostream>
static inline std::ostream& operator<<(std::ostream& os, Shared::Foo const& foo) {
os << "Foo\n================\nBars:\n";
for (auto& [f, l] : foo.bars)
os << " - " << f << ", " << l << "\n";

os << "Snafus:";
for (auto& s : foo.snafus) {
os << "\n - ";
for (auto el : s.no_problem)
os << " " << el;
}
return os << "\n";
}


int main() { Shared::Segment msm(bip::open_or_create, "my_shared_mem", 10ull << 10);
Shared::Foo& foo = *msm.find_or_construct<Shared::Foo>("the_foo") //
(msm.get_segment_manager()); // constructor arguments

foo.bars.emplace_back("John", "Doe");
foo.bars.emplace_back("Jane", "Deer");
foo.bars.emplace_back("Igor", "Stravinsky");
foo.bars.emplace_back("Rimsky", "Korsakov");

foo.snafus.push_back({1, 2, 3});
foo.snafus.push_back({2, 3, 4});
foo.snafus.push_back({3, 4, 5, 6, 7});

std::cout << foo << "\n";
}

关于c++ - 什么是 C++ 中的 "uses allocator"和 "scoped allocator"结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72311730/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com