当前位置: 首页 > wzjs >正文

企业网站推广的主要方法太原好的网站制作排名

企业网站推广的主要方法,太原好的网站制作排名,武穴网站建设,建筑人才网证书查询引问:vector 的第二个模板是 allocator,它会调用一个什么bind 之类的东西,是个什么概念? 在 C 标准库里,std::vector 模板的第二个参数确实是分配器(Allocator),它负责管理容器内部元…

引问:vector 的第二个模板是 allocator,它会调用一个什么bind 之类的东西,是个什么概念?

在 C++ 标准库里,std::vector 模板的第二个参数确实是分配器(Allocator),它负责管理容器内部元素内存的分配和释放。为了让同一个分配器类型能够为不同类型的对象分配内存(比如 vector 内部可能要给 T 以外的临时对象分配空间),标准定义了一个“重绑定”(rebind)机制。


Allocator::rebind

  1. 概念
    Allocator 是一个模板类,它只能直接分配类型 T 的内存。但在操作容器内部结构时(比如分配节点、维护内存池、构造/销毁元素),可能需要分配其他类型的内存(例如内部节点、控制块、对齐缓冲区等)。rebind 就是告诉编译器 “嘿,如果我有一个为 T 服务的分配器类型,怎么把它‘转换’成一个为 U 服务的分配器类型?”

  2. 典型定义
    在一个自定义分配器里,你可能会看到类似:

template<typename U>
struct rebind {using other = MyAllocator<U>;
};

这就声明:
给定 MyAllocator,如果想要一个 MyAllocator<U>,就通过 MyAllocator<T>::rebind<U>::other 拿到。

  1. 标准适配:allocator_traits

从 C++11 开始,标准引入了 std::allocator_traits,来统一分配器的接口。allocator_traits 会检查你的分配器类型是否定义了 rebind 嵌套模板,如果没有,则提供一个默认实现:

template<typename Alloc, typename U>
using rebinder = typename Alloc::template rebind<U>::other;

当容器需要为其他类型(如内部节点类型)分配内存时,就使用:

using NodeAlloc = typename std::allocator_traits<Allocator>::template rebind_alloc<NodeType>;

这里的 rebind_alloc 就是通过 rebind::other 或内部默认实现得到的。


在 std::vector 中的作用
• 分配元素数组
最直接的用途是为 T[] 分配内存,构造和析构 T。这是最常见的:vector<T, Alloc> 内部会用到 Alloc::allocate(n) 分配 n * sizeof(T) 字节。
• 分配内部控制结构
比如在某些实现里,vector 可能会分配额外的控制块或对齐缓冲区(通常不是用在 vector 上,但对 list、map 之类的节点容器就很常见)。
• 容器之间的拷贝/移动
当你从一个使用分配器 A1 的容器,拷贝到另一个使用分配器 A2 的容器时,如果 A1 和 A2 不是同类型,需要把 A1 重绑定到目标元素类型以便做内存复制。


小结
• rebind:分配器模板里的一个内部模板,用来“重绑定”到其他类型。
• allocator_traits:C++11+ 统一接口,检测或提供默认的 rebind 实现。
• 用途:让同一个分配器类型能在容器内部为多种类型分配内存,不仅仅是容器元素本身。

这样,无论你在容器内部需要分配的是 T、Node、还是一些内部对齐缓冲,这个机制都能让分配器“通吃”各种类型。


下面是一个简单的自定义分配器 MyAllocator,它满足 C++11 的分配器要求,并且实现了 rebind 功能。你可以用它来替换 std::allocator,例如:std::vector<int, MyAllocator>。

#include <cstddef>      // for std::size_t, std::ptrdiff_t
#include <memory>       // for std::allocator_traits
#include <new>          // for ::operator new, ::operator deletetemplate <typename T>
class MyAllocator {
public:using value_type = T;using pointer = T*;using const_pointer = const T*;using reference = T&;using const_reference = const T&;using size_type = std::size_t;using difference_type = std::ptrdiff_t;// 重绑定模板,用于为其他类型 U 分配内存template <typename U>struct rebind {using other = MyAllocator<U>;};MyAllocator() noexcept = default;// 拷贝构造允许从不同类型的 MyAllocator 复制template <typename U>MyAllocator(const MyAllocator<U>&) noexcept {}~MyAllocator() = default;// 分配 n 个 T 对象的原始内存pointer allocate(size_type n) {if (n == 0) return nullptr;// 简单地使用全局 operator newvoid* ptr = ::operator new(n * sizeof(T));return static_cast<pointer>(ptr);}// 释放从 allocate 分配的内存void deallocate(pointer p, size_type) noexcept {::operator delete(p);}// 在已分配的内存上原地构造对象template <typename U, typename... Args>void construct(U* p, Args&&... args) {::new ((void*)p) U(std::forward<Args>(args)...);}// 显式调用析构template <typename U>void destroy(U* p) {p->~U();}// 最大可分配对象数量(理论上)size_type max_size() const noexcept {return size_type(-1) / sizeof(T);}
};// 比较运算符:不同类型的 MyAllocator 总是相等的
template <typename T, typename U>
bool operator==(const MyAllocator<T>&, const MyAllocator<U>&) noexcept {return true;
}template <typename T, typename U>
bool operator!=(const MyAllocator<T>& a, const MyAllocator<U>& b) noexcept {return !(a == b);
}

说明:
1. value_type 等类型定义
标准要求分配器提供这些类型别名,以便 allocator_traits 能正确处理。
2. rebind 嵌套模板
用来将 MyAllocator<T> 变换为 MyAllocator<U>,容器内部需要为其他类型(如节点或缓冲区)分配时会用到。
3. allocate / deallocate
使用全局的 ::operator new 和 ::operator delete。在真实场景,你可以替换成自定义的内存池或对齐分配逻辑。
4. construct / destroy
在 C++17 及以前需要自定义,但从 C++20 起 allocator_traits 会使用 std::allocator_traits::construct,你可以省略这两个方法,让 allocator_traits 使用完美转发到 ::new。
5. 比较运算符
分配器之间相等意味着它们可以互换内存资源。在这里我们简单地认为所有 MyAllocator 实例都相等。

你可以像这样使用它:

#include <vector>
int main() {// 使用 MyAllocator 分配 vector 的内存std::vector<int, MyAllocator<int>> v;v.push_back(42);v.push_back(7);return 0;
}

这个示例展示了如何编写一个符合标准分配器接口、支持重绑定(rebind)的最简实现。


在 std::vector<T, Alloc> 的实现中,会通过 allocator_traits<Alloc>::rebind_alloc<U>(或直接用 Alloc::rebind<U>::other)来为不同用途分配内存。下面给出几个典型场景和简化示例,说明它们如何“引用”到 other:

  1. 分配元素数组

当你做 vector.reserve(n) 或第一次插入元素时,vector 需要为 n 个元素分配一片连续内存。它会这样写:

using AllocTraits = std::allocator_traits<Alloc>;
using TAlloc      = Alloc;                // 原始的元素分配器
using UAlloc      = AllocTraits::          // 重绑定到 Ttemplate rebind_alloc<T>;  // … 在成员函数里 …
UAlloc alloc = get_allocator();           // 拿到一个 T 分配器实例
pointer data = AllocTraits::allocate(     // 调用 allocate(n)alloc, static_cast<size_type>(n)
);

在 C++11 以前,等价于:

using UAlloc = typename Alloc::template rebind<T>::other;
UAlloc alloc = static_cast<const UAlloc&>(get_allocator());
pointer data = alloc.allocate(n);

这里的 rebind::other 就是 MyAllocator 或 std::allocator。


  1. 重新分配(grow)时的临时缓冲

当 vector 扩容(从旧容量 cap 增长到新容量 new_cap)时,会:

//	1.	先通过重绑定分配一块更大的内存:
UAlloc tmp_alloc = get_allocator();
T* new_buf = tmp_alloc.allocate(new_cap);
// 2.	将旧元素原地拷贝或移动到新缓冲区:
for (size_type i = 0; i < size(); ++i) {AllocTraits::construct(tmp_alloc, new_buf + i, std::move_if_noexcept(data_[i]));
}
// 3.	销毁、释放旧内存,切换指针:
for (size_type i = 0; i < size(); ++i)AllocTraits::destroy(alloc, data_[i]);
alloc.deallocate(data_, cap);
data_ = new_buf;
cap   = new_cap;

  1. 拷贝或移动构造另一个 vector

当你做 vector<int, MyAlloc> v2(v1); 时,如果 MyAlloc 支持跨类型拷贝:

template <class Alloc2>
vector(const vector<T,Alloc2>& other,const Alloc& alloc /* = Alloc()*/): alloc_(alloc), size_(other.size()), cap_(other.size())
{using UAlloc2 = typename Alloc2::template rebind<T>::other;UAlloc2 src_alloc(other.get_allocator());data_ = alloc_traits::allocate(alloc_, cap_);for (size_type i = 0; i < size_; ++i) {alloc_traits::construct(alloc_, data_ + i,other.data_[i]);}
}

这里,Alloc2::rebind::other 用来从 other 的分配器类型里拿到一个能分配 T 的实例。

  1. 插入时的异常安全缓冲

对于强异常安全保证,vector 插入可能在临时缓冲区中先做完整构造,然后才切换到正式内存。依然用同一个 rebind::other:

// 简化伪码
UAlloc temp_alloc = get_allocator();
pointer temp_buf = temp_alloc.allocate(cap_ + 1);try {// 构造 [0, pos) 旧元素for (...) construct(temp_buf + i, data_[i]);// 构造新元素construct(temp_buf + idx, value);// 构造剩余旧元素for (...) construct(temp_buf + j, data_[j-1]);
}
catch(...) {// 析构已经构造的元素for(...) destroy(temp_buf + k);temp_alloc.deallocate(temp_buf, cap_ + 1);throw;
}// 到此无异常,切换到 temp_buf ...

小结
• Alloc::rebind<U>::other 或 allocator_traits<Alloc>::rebind_alloc<U>
• 场景:初次分配元素数组、扩容重分配、跨分配器拷贝构造、异常安全插入等。
• 作用都是:把一个“只能分配 T”的分配器,变成“能分配 U”的分配器,供 vector 各种内部机制使用。

通过这些例子,可以看到 other 是如何被 std::vector 在内存管理各环节中反复引用的。


文章转载自:

http://n55an0fu.zknjy.cn
http://2TZ9fdfS.zknjy.cn
http://rtS3xZQs.zknjy.cn
http://cZkElUkK.zknjy.cn
http://SiosLsad.zknjy.cn
http://6lR1FQZW.zknjy.cn
http://2NKfnP5u.zknjy.cn
http://Y6wfdkIC.zknjy.cn
http://EpSy2s7r.zknjy.cn
http://8Fx6uFTR.zknjy.cn
http://ge0MGUeq.zknjy.cn
http://xzFJcow9.zknjy.cn
http://CIbvnRmo.zknjy.cn
http://Urj1wVR1.zknjy.cn
http://DB3jsBCf.zknjy.cn
http://ayZoBKBr.zknjy.cn
http://wikOdAMT.zknjy.cn
http://I0pvUqW3.zknjy.cn
http://VsiIhefa.zknjy.cn
http://bfnk0TgG.zknjy.cn
http://99ADXABn.zknjy.cn
http://QyqcndzC.zknjy.cn
http://vk8fp1ga.zknjy.cn
http://S4AdX2vg.zknjy.cn
http://GjbGZ3pZ.zknjy.cn
http://DHhVMpL2.zknjy.cn
http://lGdk2SYY.zknjy.cn
http://F816nC5b.zknjy.cn
http://3rCHuRAv.zknjy.cn
http://IYlBtZnj.zknjy.cn
http://www.dtcms.com/wzjs/614270.html

相关文章:

  • 百度上公司做网站西京一师一优课建设网站
  • 网站开发选题背景微信小程序开发团队
  • 网站建设 司法公开的需要怎么在百度上做自己的网站
  • 建设银行网站首页打不开网站制作宜昌怎么做?
  • 汕头行业网站徐州微信网站建设
  • 成都网站建设兴田德润实力强中牟县建设局网站
  • 刚做的网站为什么百度搜不出来长春哪有做网站公司
  • wordpress站点统计网站建设做的人多吗
  • 郑州网站营销推广重庆旅游网站
  • 怎么做影视网站wordpress 百度 seo
  • 厦门优化网站排名中国外发加工网app
  • 网站运营主要做什么工作帝国cms做门户网站
  • 网站建设项目验收方案安徽工程建设官方网站
  • 做网站图标的软件wordpress5导航图标
  • 网站建设数据录入免费虚拟房屋设计软件
  • 东莞公司网站建设公司哪家好分销订单管理系统
  • 搜索引擎的网站有哪些wordpress底部音频
  • 最新网站建设进度表门户网站模式
  • 网站开发合同的缺陷东莞建设网网上平台
  • 轴承网站建设快速网站建设推荐
  • 电商网站开发需要多少钱做企业网站需要注意什么
  • 河北城乡建设厅网站显示不全知识库wordpress插件
  • 湖州佳成建设网站学校专业群建设专题网站
  • 厦门免费建立企业网站湖南郴州市房价
  • 咸阳企业网站建设常州网站建站
  • 建设工程信息在哪个网站云存储做网站
  • 网站怎么推广软文网站建设费计入无形资产
  • 重庆李健做网站广东 网站建设 公司排名
  • 怎么简单页网站四川住房城乡建设官网
  • 河北省建设工程质量监督网站网站开发技术书籍