斯蒂芬·拉瓦维的 Mallocator 在 C++11 中是一样的吗?
Is Stephen Lavavej's Mallocator the same in C++11?
8年前,Stephen Lavavej发表了一篇博客文章,其中包含一个简单的分配器实现,名为"Mallocator"。从那时起,我们已经过渡到了C++11时代(很快也过渡到了C++17时代)。。。新的语言特性和规则会影响Mallocator吗?还是它仍然相关?
STL自己在2014年CppCon(从26'30开始)的STL特性和实现技术演讲中已经回答了这个问题。
幻灯片在github上。
我合并了下面幻灯片28和29的内容:
#include <stdlib.h> // size_t, malloc, free
#include <new> // bad_alloc, bad_array_new_length
template <class T> struct Mallocator {
typedef T value_type;
Mallocator() noexcept { } // default ctor not required
template <class U> Mallocator(const Mallocator<U>&) noexcept { }
template <class U> bool operator==(
const Mallocator<U>&) const noexcept { return true; }
template <class U> bool operator!=(
const Mallocator<U>&) const noexcept { return false; }
T * allocate(const size_t n) const {
if (n == 0) { return nullptr; }
if (n > static_cast<size_t>(-1) / sizeof(T)) {
throw std::bad_array_new_length();
}
void * const pv = malloc(n * sizeof(T));
if (!pv) { throw std::bad_alloc(); }
return static_cast<T *>(pv);
}
void deallocate(T * const p, size_t) const noexcept {
free(p);
}
};
请注意,它正确地处理了分配中可能出现的溢出。
正如@kerrek所建议的,这里有一个Mallocator,它基于链接的竞技场分配器,删除了竞技场部分。
template<class T>
struct Mallocator11 {
using value_type = T;
using pointer = T*;
using propagate_on_container_copy_assignment = std::true_type;
using propagate_on_container_move_assignment = std::true_type;
using propagate_on_container_swap = std::true_type;
Mallocator11(Mallocator11 const&) = default;
Mallocator11& operator=(Mallocator11 const&) = default;
Mallocator11()=default;
template<class U>
Mallocator11(Mallocator11<U> const&) noexcept {}
template<class U>
Mallocator11& operator=(Mallocator11<U> const&) noexcept {return *this}
pointer allocate(std::size_t n) {
if (std::size_t(-1) / sizeof(T) < n)
throw std::bad_array_new_length(); // or something else
if (!n) return nullptr; // zero means null, not throw
if(auto*r= static_cast<pointer>(malloc(n * sizeof(T))))
return r;
throw std::bad_alloc();
}
void deallocate(pointer p, std::size_t n) {
free(p);
}
template<class U>
bool operator==(Mallocator11<U> const& rhs) const {
return true;
}
template<class U>
bool operator!=(Mallocator11<U> const& rhs) const {
return false;
}
};
更少的代码。推广的一些特性。
相关文章:
- MSVC是否支持C++11样式的属性而不是__declspec
- 创建LinkedList退出,返回代码为-11(SIGSEGV)
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 如何将模板转换为C++11之前的模板
- c++11评估顺序(未定义的行为)
- C++中的VLA,扩展名为std=C++11
- 代码在我的计算机上运行良好,但是在将其提交给coursera时遇到未知的信号11问题
- "类模板示例<int>;"语句对 C++11 是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 如何使用lock_guard在c++11中实现scoped_lock功能
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- C++11 中不同类型的对象的 std::array 的替代方案
- 为什么 -mmacosx-version-min=10.10 不阻止使用标记为从 10.11 开始的函数?
- 为什么我的C++代码中出现'Segmentation Fault: 11'行?
- C++11: 如何编写一个像 Get 一样工作的模板函数<tuple>...但是收到参数包?
- 是否有一个很好的方法可以在C 11中打印出像JSON一样的Trie结构(仅迭代解决方案)的扁平命名空间
- 学习 c++11 智能指针,它不会让我像指针一样使用隐式转换吗?
- 斯蒂芬·拉瓦维的 Mallocator 在 C++11 中是一样的吗?
- 在多线程中使用c++ 11随机库生成随机数是否像在多线程中使用rand()一样慢