作为关联容器键的数据成员指针
Data member pointers as associative container keys
我正在尝试创建一个 pointers to data members 的 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 是否有任何更改使得可以使用指向数据成员的指针作为标准关联容器的键?
按字节比较它们,例如使用这个比较器:
#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。
我正在尝试创建一个 pointers to data members 的 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 是否有任何更改使得可以使用指向数据成员的指针作为标准关联容器的键?
按字节比较它们,例如使用这个比较器:
#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。