7

我正在尝试创建一个指向数据成员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
};

它产生错误error: invalid operands of types 'int foo::* const' and 'int foo::* const' to binary 'operator<'。完整的错误消息还暗示这发生在std::less.

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

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

4

1 回答 1

8

逐字节比较它们,例如使用这个比较器:

#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;
    }
};

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

于 2022-01-06T16:03:21.937 回答