标准草案N4618关于std::pmr::monotonic_buffer_resource对此进行了说明:



换句话说,标准不仅希望将相等性的指针与this == &rhs进行比较,还希望供应商不遗余力地对右侧指针进行dynamic_cast

我无法想到dynamic_cast会改变比较结果的任何理智的情况。我可以想到一些疯狂的情况:

class new_delete_memory_resource : public memory_resource {
    void *do_allocate(size_t bytes, size_t align) override {
        return ::operator new(bytes, align);
    }
    void *do_deallocate(void *p, size_t bytes, size_t align) override {
        ::operator delete(p, bytes, align);
    }
    bool do_is_equal(const memory_resource& rhs) const noexcept override {
        return (this == &rhs);
    }
};
class TwoHeadedResource :
    public new_delete_memory_resource,
    public monotonic_buffer_resource
{
};

TwoHeadedResource thr;
memory_resource *a = static_cast<new_delete_memory_resource *>(thr);
memory_resource *b = static_cast<monotonic_buffer_resource *>(thr);

assert(*a != *b);
assert(*b == *a);

这种差异有微妙的原因吗?如果标准通过删除operator==使dynamic_cast自反/对称/可传递,那会出什么问题?

最佳答案

这是一个已知的缺陷,尽管您的问题确实提醒我我需要提交正式的问题报告。
this == &other的简单表述应该是这样。 dynamic_cast是某些样板代码的保留,因此相等的rhs不必与lhs是相同的对象才能被视为相等。在最一般的情况下,如果两个pmr::memory_resource对象是可互换的,但没有相同的地址,则必须动态地将rhs强制转换为lhs的类型,以便确定相等性。但是,对于pmr::monotonic_buffer_resource,要求地址相等,因此dynamic_cast是多余的。

不过,您的TwoHeadedResource很聪明。向您致谢,以找出可能会有所作为的情况,即使这不是我们旨在支持的代码类型。 :-)

编辑:现在在http://cplusplus.github.io/LWG/lwg-active.html#3000上有此缺陷的官方问题报告。

09-12 13:11