- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想设计一个类模板,它采用分配器类型(如标准第 17.6.3.5 节中所定义)作为模板参数。我怎么看std::allocator_traits<A>
有助于填补 A
的任何缺失成员使用默认设置。除此之外,标准库或 boost 中是否有任何有助于正确使用分配器的内容?
特别是:
尊重类型定义,如 std::allocator_traits<A>::propagate_on_container_copy_assignment
, 我是否必须在每个类的特殊成员函数中检查这些东西,每个类都有一个 A
类型的成员? ?或者是否有一些包装器类型我可以用作成员来代替它来处理这些东西?
如果我想通过在用户可见对象旁边存储额外数据来过度分配以减少分配次数,像这样重新绑定(bind)分配器是否合适?
.
template<typename T, typename A>
class MyClass
{
private:
//...
struct storage {
int m_special_data;
T m_obj;
};
typedef typename std::allocator_traits<A>::template rebind_alloc<storage>
storage_alloc;
typedef typename std::allocator_traits<A>::template rebind_traits<storage>
storage_traits;
storage_alloc m_alloc;
static T* alloc(T&& obj)
{
storage_traits::pointer sp = storage_traits::allocate(m_alloc, 1);
sp->m_special_data = 69105;
return ::new(&sp->m_obj) T(std::move(obj));
}
//...
};
最佳答案
我不知道有什么可以让生活更轻松,allocator_traits
确实通过提供所有样板代码使编写分配器变得更简单,但它无助于使用分配器。
因此我可以在 C++03 和 C++11 代码中使用单个分配器 API,我添加了 <ext/alloc_traits.h>
到 GCC 4.7,类模板 __gnu_cxx::__alloc_traits
提供使用 allocator_traits
的一致 API在C++11模式下,在C++03模式下直接在分配器上调用相关成员函数。
不,没有包装器或快捷方式,C++11 分配器要求使容器作者的工作很多变得更加复杂。每个容器的要求略有不同,具体取决于它管理内存的方式。对于类似 vector 的类型,在复制赋值运算符中 if propagate_on_container_copy_assignment
(POCCA) 为 false 并且现有容量大于源对象的大小,那么您可以重新使用现有内存(如果 POCCA 为 true 并且新分配器不相等,则您不能重新使用旧内存,因为它赢了在分配器被替换后,稍后不可能取消分配它),但这种优化对基于节点的容器(例如列表或映射)帮助不大。
这看起来几乎是正确的,尽管您可能想要替换
return ::new(&sp->m_obj) T(std::move(obj));
与
A a(m_alloc);
std::allocator_traits<A>::construct(a, &sp->m_obj, std::move(obj));
return &sp->m_obj;
如 [container.requirements.general]/3 中所述,使用分配器的容器使用 allocator_traits<A>::construct
创建元素类型 T
本身但分配的任何其他类型(例如您的 storage
)不得使用 construct
.
如果storage
本身被构造然后它将构造storage::m_obj
除非该成员是可以保留未初始化的类型,例如 std::aligned_storage<sizeof(T)>
,稍后可以通过 allocator_traits<A>::construct
显式初始化.或者,单独构造每个需要非平凡构造的成员,例如如果storage
还有一个string
成员:
storage_traits::pointer sp = storage_traits::allocate(m_alloc, 1);
sp->m_special_data = 69105;
::new (&sp->m_str) std::string("foobar");
A a(m_alloc);
std::allocator_traits<A>::construct(a, &sp->m_obj, std::move(obj));
return &sp->m_obj;
m_special_data
member 是一个简单的类型,所以它的生命周期在为它分配存储空间后就开始了。 m_str
和 m_obj
成员需要非平凡的初始化,因此它们的生命周期从构造函数完成时开始,这是通过放置 new 和 construct
完成的。分别调用。
编辑:我最近了解到该标准存在缺陷(我已报告)和对 construct
的调用不需要使用反弹分配器,所以这些行:
A a(m_alloc);
std::allocator_traits<A>::construct(a, &sp->m_obj, std::move(obj));
可以替换为:
std::allocator_traits<storage_alloc>::construct(m_alloc, &sp->m_obj, std::move(obj));
这让生活稍微轻松一些。
关于c++ - 使用 std::allocator_traits<A>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9689328/
C++11 提供了 std::allocator_traits 类作为使用分配器的标准方式。静态函数 std::allocator_traits::construct() 将一个指针 指向应该构造对象
using namespace std::rel_ops; template > class my_vector { public: typedef A
如果Allocator符合标准库分配器接口(interface),调用std::allocator_traits::deallocate是否安全用空指针?我知道是什么时候 Allocator是std:
std::allocator_traits当我提供一个带有单个模板参数的分配器的 STL 样式容器时,它会自动发挥它的魔力,但当我提供一个带有两个模板参数但其他方面相似的分配器的 STL 样式容器时,
我想设计一个类模板,它采用分配器类型(如标准第 17.6.3.5 节中所定义)作为模板参数。我怎么看std::allocator_traits有助于填补 A 的任何缺失成员使用默认设置。除此之外,标准
我想定制std::vector不默认构造元素类型的行为(例如 int ),因为对大型 vector 执行此操作的成本很高。 看看这个,我能看到的唯一方法就是专门化 std::allocator_tra
受到 Haskell 的启发,我尝试像这样实现 std::forward_list: namespace std { template > class forward_list {
分配器可以选择嵌套类型,如 pointer , const_pointer .但是可以始终将这些接口(interface)与 std::allocator_traits 一起使用,如果这些类型在 Al
我正在尝试实现一个 STL 风格的容器类,我有一个关于在我的类中使用分配器的问题: STL 的 allocator_traits 中的静态成员函数有何用途? 直到现在,我认为我应该实例化 alloca
我不了解 C++ 11 中的 allocator_traits,所以我尝试了 allocator_traits exmple来自 cplusplus 网站。但是,此代码无法在 gcc 4.9、VS 2
我有一个结构定义为: struct Foo { double x; double y; }; 我有一个将这个结构作为参数的函数: void doSomethingWithFoo(Foo
我很想理解boost::container::allocator_traits当我遇到 boost::container::allocator_traits::is_partially_propaga
下面的代码可以正常编译: #include #include int main() { const int * a = new int(5); std::cout >; auto alloc =
我想这个问题真的是关于 std::allocator_traits 的设计的并提供自定义分配器。如果我想构造一个 std::shared_ptr<>使用自定义分配器,我可以使用 std::alloca
为什么 C++0x 无序关联容器不使用 allocator_traits 来定义它们的成员类型 pointer 和 const_pointer? 例如,顺序关联容器和有序关联容器使用以下定义: typ
我正在尝试重新绑定(bind)我的自定义分配器类型,MyAllocator , 用于 basic_string类,例如: std::basic_string, MyAllocator> ... 分配器
为什么没有标准 C++03 接口(interface)用于查询 C++0x 中使用的分配器的成员类型?成员类型不足的用例有哪些? 最佳答案 为了从设计模式的角度解释 allocator_traits,
根据 http://en.cppreference.com/w/cpp/concept/Allocator ,一个可以用作分配器类型的类必须满足许多要求。但是,我找不到 C++ 标准指定的相同要求。该
我是一名优秀的程序员,十分优秀!