- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在为 C++ 开发基于段的内存分配器。在这个分配器中,当你释放一 block 内存时,你必须知道它来自哪个段。因此,我将指向该段的指针存储为花式 pointer
的成员。从分配器的 allocate
返回功能。
只是为了显示我所说的界面:这里是 fancy_memory_resource
支持我的分配器...
template<class Ptr>
class fancy_memory_resource {
public:
Ptr allocate(size_t bytes, size_t align = alignof(max_align_t)) {
return do_allocate(bytes, align);
}
void deallocate(Ptr p, size_t bytes, size_t align = alignof(max_align_t)) {
return do_deallocate(p, bytes, align);
}
bool is_equal(const fancy_memory_resource& rhs) const noexcept {
return do_is_equal(rhs);
}
virtual ~fancy_memory_resource() = default;
private:
virtual Ptr do_allocate(size_t bytes, size_t align) = 0;
virtual void do_deallocate(Ptr p, size_t bytes, size_t align) = 0;
virtual bool do_is_equal(const fancy_memory_resource& rhs) const noexcept = 0;
};
(注意 std::pmr::memory_resource
可以实现为 fancy_memory_resource<void*>
的类型定义。这是我故意的。)
与此同时,Ptr
有问题的是一个名为 segmented_fancy_pointer<T>
的奇特指针类型(未图示)继承自 CRTP 类型 fancy_ptr_base<T, segmented_fancy_pointer<T>>
...
template<class T, class CRTP>
struct fancy_ptr_base {
constexpr T *ptr() const noexcept { return m_ptr; }
constexpr explicit operator T*() const noexcept { return ptr(); }
constexpr explicit operator bool() const noexcept { return ptr() != nullptr; }
constexpr bool operator==(CRTP b) const { return ptr() == b.ptr(); }
constexpr bool operator!=(CRTP b) const { return ptr() != b.ptr(); }
constexpr bool operator==(decltype(nullptr)) const { return ptr() == nullptr; }
constexpr bool operator!=(decltype(nullptr)) const { return ptr() != nullptr; }
constexpr bool operator<(CRTP b) const { return ptr() < b.ptr(); }
constexpr bool operator<=(CRTP b) const { return ptr() <= b.ptr(); }
constexpr bool operator>(CRTP b) const { return ptr() > b.ptr(); }
constexpr bool operator>=(CRTP b) const { return ptr() >= b.ptr(); }
constexpr T& operator*() const noexcept { return *ptr(); }
constexpr T* operator->() const noexcept { return ptr(); }
constexpr CRTP& operator+=(ptrdiff_t i) { m_ptr += i; return as_crtp(); }
constexpr CRTP& operator-=(ptrdiff_t i) { m_ptr -= i; return as_crtp(); }
constexpr CRTP& operator++() { ++m_ptr; return as_crtp(); }
constexpr CRTP& operator--() { --m_ptr; return as_crtp(); }
constexpr CRTP operator++(int) { auto r(as_crtp()); ++*this; return r; }
constexpr CRTP operator--(int) { auto r(as_crtp()); --*this; return r; }
constexpr CRTP operator+(ptrdiff_t i) const { auto r(as_crtp()); r += i; return r; }
constexpr CRTP operator-(ptrdiff_t i) const { auto r(as_crtp()); r -= i; return r; }
constexpr ptrdiff_t operator-(CRTP b) const { return ptr() - b.ptr(); }
protected:
T *m_ptr = nullptr;
private:
constexpr CRTP& as_crtp() { return *static_cast<CRTP*>(this); }
constexpr const CRTP& as_crtp() const { return *static_cast<const CRTP*>(this); }
};
template<class CRTP>
struct fancy_ptr_base<void, CRTP> {
constexpr void *ptr() const noexcept { return m_ptr; }
constexpr explicit operator void*() const noexcept { return ptr(); }
constexpr explicit operator bool() const noexcept { return ptr() != nullptr; }
constexpr bool operator==(CRTP b) const { return ptr() == b.ptr(); }
constexpr bool operator!=(CRTP b) const { return ptr() != b.ptr(); }
constexpr bool operator==(decltype(nullptr)) const { return ptr() == nullptr; }
constexpr bool operator!=(decltype(nullptr)) const { return ptr() != nullptr; }
constexpr bool operator<(CRTP b) const { return ptr() < b.ptr(); }
constexpr bool operator<=(CRTP b) const { return ptr() <= b.ptr(); }
constexpr bool operator>(CRTP b) const { return ptr() > b.ptr(); }
constexpr bool operator>=(CRTP b) const { return ptr() >= b.ptr(); }
protected:
void *m_ptr = nullptr;
};
现在是真正的问题。当我去使用我的 segmented_allocator<T>
(未显示)与 libc++ 的 std::vector
,一切正常。当我尝试将它与 libstdc++ 的 std::vector
一起使用时, 它失败了:
In file included from /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_algobase.h:67:0,
from /opt/wandbox/gcc-head/include/c++/8.0.0/vector:60,
from prog.cc:1984:
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_iterator.h: In instantiation of 'class __gnu_cxx::__normal_iterator<scratch::segmented_fancy_pointer<int>, std::vector<int, scratch::pmr::propagating_polymorphic_allocator<int, scratch::segmented_fancy_pointer<int> > > >':
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/vector.tcc:105:25: required from 'std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {int}; _Tp = int; _Alloc = scratch::pmr::propagating_polymorphic_allocator<int, scratch::segmented_fancy_pointer<int> >; std::vector<_Tp, _Alloc>::reference = int&]'
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_vector.h:954:21: required from 'void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = int; _Alloc = scratch::pmr::propagating_polymorphic_allocator<int, scratch::segmented_fancy_pointer<int> >; std::vector<_Tp, _Alloc>::value_type = int]'
prog.cc:1990:18: required from here
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_iterator.h:770:57: error: no type named 'iterator_category' in 'struct std::iterator_traits<scratch::segmented_fancy_pointer<int> >'
typedef typename __traits_type::iterator_category iterator_category;
^~~~~~~~~~~~~~~~~
现在,我可以通过将“迭代器特征”typedef 添加到 fancy_ptr_base<T, CRTP>
来解决这个问题,像这样:
using pointer = CRTP;
using reference = T&;
using value_type = std::remove_cv_t<T>;
using iterator_category = std::random_access_iterator_tag;
using difference_type = ptrdiff_t;
但是我必须这样做吗?是否要求每个花哨的指针类型也都是迭代器类型?或者 libc++ 是否在做正确的事情而 libstdc++ 的 vector
只是有一个错误?
(我已经说服自己 most iterators are not fancy pointers。这个问题是由于我突然怀疑也许所有花哨的指针确实是迭代器。)
最佳答案
是的,您需要执行 Random Access Iterator 的所有要求. C++ 标准 [allocator.requirements]/5:
An allocator type
X
shall....X::pointer
andX::const_pointer
shall also satisfy the requirements for a random access iterator.
特别是,您的奇特指针类型需要每个 iterator 所需的五个成员类型.
你好像也不见了fancy_memory_resource<Ptr>::value_type
,几个需要的非成员函数,以及一些 noexcept
关键字。请查看requirements for allocator types以及它们的指针类型。
关于c++ - 每个花哨的指针都应该是一个迭代器吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45132546/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!