作为关联容器键的数据成员指针

Fra*_*eux 6 c++ std data-member-pointers c++17 c++20

我正在尝试创建一个指向数据成员的std::set指针。但是,我找不到对此类指针进行排序或散列的方法。

它们不能与 进行比较operator<,它们似乎不受 的支持std::less,并且没有标准整数类型可以保证保存它们的表示(它们可能不适合std::uintptr_t)。

这是我首先尝试的(https://godbolt.org/z/K8ajn3rM8):

#include <set>

struct foo
{
    int x;
    int y;
};

using t_member_ptr = int (foo::*);

const std::set<t_member_ptr> members = {
    &foo::x,
    &foo::y
};
Run Code Online (Sandbox Code Playgroud)

它会产生错误error: invalid operands of types 'int foo::* const' and 'int foo::* const' to binary 'operator<'。完整的错误消息还暗示在 的实例化期间发生这种情况std::less

我发现了一个类似的问题(指向成员的指针集),但它可以追溯到 C++14,答案归结为“将指针放入向量中并执行线性搜索”。

C++17 或 C++20 是否有任何更改使得可以使用指向数据成员的指针作为标准关联容器的键?

Hol*_*Cat 7

按字节比较它们,例如使用此比较器:

#include <cstring>
#include <type_traits>

struct BitLess
{
    template <typename T>
    requires std::has_unique_object_representations_v<T>
    constexpr bool operator()(const T &a, const T &b) const
    {
        return std::memcmp(reinterpret_cast<const char *>(&a), reinterpret_cast<const char *>(&b), sizeof(T)) < 0;
    }
};
Run Code Online (Sandbox Code Playgroud)

检查std::has_unique_object_representations_v<T>确保内部没有填充物。它在 GCC、Clang 和 MSVC 上进行了尝试,并且对于所有三个上的成员指针都返回 true。