std::allocator的construct和destroy成员函数上构造元素的类型参数化:
template<class T>
class allocator
{
public:
typedef T value_type;
typedef T* pointer;
template<class U, class... Args>
void construct(U *p, Args&&... args);
template<class U>
void destroy(U *p);
...
};
Run Code Online (Sandbox Code Playgroud)
这是什么理由?为什么他们不采取value_type*或pointer?似乎allocator<T>应该只知道如何构造或销毁类型的对象T.
STL中是否有基于malloc/free的分配器?如果没有,有没有人知道一个简单的复制/粘贴?我需要它为一个不能调用new/delete的地图.
如何std::list分配保存next/ prev指针的节点及其T包含的元素?
我认为标准分配器只能用于为一种类型std::allocator::allocate分配内存(因为以递增的方式分配内存sizeof(T)).因此,似乎不可能在单个分配中分配列表节点和包含的对象,这意味着必须使用实现决定的任何方式分配节点,并且节点存储指向对象而不是对象本身的指针,这意味着两个级别的间接从指向列表节点的指针到它包含的对象,这似乎是低效的.是这样的吗?
"经典"STL容器例如std::vector并将std::map其分配器类型作为模板参数.这意味着,std::vector<T, std::allocator<T>>和std::vector<T, MyAllocator>例如被视为完全独立的类型.
一些较新的分配感知类,如std::shared_ptr和std::tuple,另一方面利用类型擦除约分配器"隐藏"的信息,所以它不会形成类型签名的一部分.但是,std::unordered_map(具有类似的年份shared_ptr)保持了采用额外默认模板参数的经典方法.
问题:
处理std::vector<T, std::allocator<T>>和std::vector<T, MyAllocator>作为不同类型被认为是可取的,还是只是在STL编写时类型擦除的副作用不是众所周知的技术?
以这种方式使用类型擦除有哪些缺点(如果有的话)?
类型擦除的分配器是否总是首选新容器?
我目前正致力于编写池分配器.我的问题归结为以下代码:
template <typename T>
union myUnion {
T data;
myUnion<T>* nextUnion;
};
void someFunction(){
myUnion<T> mu;
T* t = new (std::addressof(mu.data)) T();
//some code
myUnion<T>* mu2 = reinterpret_cast<myUnion<T>*>(t);
}
Run Code Online (Sandbox Code Playgroud)
mu的地址是否与mu2相同?
在此上下文中T是某种类型,并且allocator是该类型的分配器对象.默认情况下,std::allocator<T>但这不一定是真的.
我有一大堆记忆allocator.allocate(n).我也有一个容器con中T的对象(比如,一个std::vector<T>).我想用T对象初始化那块内存.
存储块的位置存储在T* data.
这两个代码示例是否始终相同?
#include <memory>
// example 1
std::uninitialized_copy(con.begin(), con.end(), data)
// example 2
std::vector<T>::const_iterator in = con.begin();
for (T* out = data; in != con.end(); ++out, ++in) {
allocator.construct(out, *in);
}
Run Code Online (Sandbox Code Playgroud)
对于这两个?
#include <memory>
T val = T(); // could be any T value
// example 3
std::uninitialized_fill(data, data + n, val)
// example 4
for (T* out = …Run Code Online (Sandbox Code Playgroud) 我想用更健壮的分配器替换标准分配器(C++ 标准只需要对 vector::resize 进行溢出检查)。许多库随附的各种 C++ 分配器在接受负面自测时表现不佳。
我可以使用更强大的分配器。ESAPI 的分配器不仅检查溢出,它还具有调试工具来帮助发现错误。http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/zAllocator.h。
是否有一种标准方法可以轻松替换程序中使用的 C++ 分配器?我还想确保它在库代码中被替换,我可能无法访问源代码。
STL 中所有分配器感知类模板都必须使用分配器类型进行实例化。如果分配器不是模板参数而是模板 模板参数,对用户来说不是更方便吗?
为了演示,std::vector 和 std::basic_string 类模板分别具有以下签名:
template<class T, class Allocator = std::allocator<T>> class vector;
template<class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT>> class basic_string;
Run Code Online (Sandbox Code Playgroud)
如果我有一个自定义分配器:
template <typename T>
class MyAllocator
{
// ...
};
Run Code Online (Sandbox Code Playgroud)
并且想要实例化一个字符串向量,该向量使用我的自定义分配器为向量和字符串的内部字符数组分配内部存储,事情很快就会变得尴尬:
typedef std::vector<std::basic_string<char, std::char_traits<char>, MyAllocator<char> >, MyAllocator<std::basic_string<char, std::char_traits<char>, MyAllocator<char>>>> CustomAllocStringVector;
Run Code Online (Sandbox Code Playgroud)
使用附加的 typedef,可以稍微简化:
typedef std::basic_string<char, std::char_traits<char>, MyAllocator<char>> CustomAllocString;
typedef std::vector<CustomAllocString, MyAllocator<CustomAllocString>> CustomAllocStringVector;
Run Code Online (Sandbox Code Playgroud)
但困扰我的是,为什么强制用户显式指定分配器的完整类型?如果我将分配器用于char向量,那么不应该说分配器的类型为 allocator< char > 吗?
如果 std::vector 和 std::basic_string 的签名是:
template<typename T, template <typename ElementType> class …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个分配器,它允许我使用带有 STL 类型的boost::interprocess::offset_ptr的“花哨”指针。
\n作为一个独立的模板,指针本身工作得很好,但我很难让它与std::vector或boost::containers::vector
我为指针实现的事情列表是:
\ntemplate<class T>\nclass OffsetPtr ...\nRun Code Online (Sandbox Code Playgroud)\n迈克·阿克顿 (Mike Acton)在他的演讲“为引擎开发人员解决正确的问题”中说
绝大多数时候,您所需要的只是这三种类型的分配器:块分配器、堆栈分配器和临时分配器
但是,他没有详细说明这些类型的分配器之间的差异。
我认为“堆栈分配器”只是一个基于堆栈的分配器,但我听说过的所有其他类型(包括“arena”)听起来像是做同样事情的奇特方法,即“分配一个大块”并以一种有效的方式将其分成块,然后在完成后释放它”
那么,这些分配器之间有什么区别,各自的优点是什么,为什么我“绝大多数时候”只需要这三个?
allocator ×10
c++ ×10
c++11 ×3
stl ×3
allocation ×1
c ×1
game-engine ×1
stdlist ×1
templates ×1
type-erasure ×1