如何在 struct 中使用 boost::multi_index with struct?
How to using boost::multi_index with struct in struct?
我有一个向量,其中包含名为 ST_ThepInfo 的信息。
我的问题是在 struct Infovalue_t.
中使用 struct ST_ThepInfo
struct ST_ThepInfo
{
int length;
string ex;
int weight;
};
struct Infovalue_t {
ST_ThepInfo s;
int i;
};
struct ST_ThepInfo_tag {};
typedef boost::multi_index_container<
Infovalue_t,
boost::multi_index::indexed_by<
boost::multi_index::random_access<>, // this index represents insertion order
boost::multi_index::hashed_unique<
boost::multi_index::tag<ST_ThepInfo_tag>,
boost::multi_index::member<Infovalue_t, ST_ThepInfo,&Infovalue_t::s>>
>
> myvalues_t;
然后我调用这些代码:
myvalues_t s;
ST_ThepInfo k;
....
auto t = count.emplaceback(k, 0);
但是我得到这样的错误:
我该如何解决?
散列索引要求键类型是可散列的并且equality-comparable。
您需要为信息结构提供这些:
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index_container.hpp>
namespace bmi = boost::multi_index;
struct STInfo {
int length;
std::string ex;
int weight;
auto key_fields() const { return std::tie(length, ex, weight); }
friend size_t hash_value(STInfo const& info) {
using boost::hash_value;
return hash_value(info.key_fields());
}
bool operator==(STInfo const& other) const {
return key_fields() == other.key_fields();
}
};
struct Infovalue_t {
STInfo s;
int i;
};
using Table = bmi::multi_index_container< //
Infovalue_t, //
bmi::indexed_by< //
bmi::random_access<>, // represents insertion order
bmi::hashed_unique< //
bmi::tag<struct byInfo>, //
bmi::member<Infovalue_t, STInfo, &Infovalue_t::s>> //
>>;
#include <fmt/ranges.h>
#include <fmt/ostream.h>
struct Format : fmt::formatter<int> {
auto format(STInfo const& info, auto& ctx) const {
return fmt::format_to(ctx.out(), "{}", info.key_fields());
}
auto format(Infovalue_t const& iv, auto& ctx) const {
return fmt::format_to(ctx.out(), "({}, {})", iv.s, iv.i);
}
};
template<> struct fmt::formatter<Infovalue_t> : Format{};
template<> struct fmt::formatter<STInfo> : Format{};
int main() {
Table count;
STInfo k;
count.push_back({STInfo{42, "LtUaE", 99}, 30});
count.push_back({STInfo{43, "SomethingElse", 98}, 40});
count.push_back({STInfo{44, "SomethingElse", 97}, 30});
fmt::print("{}\n", count);
}
打印:
[((42, "LtUaE", 99), 30), ((43, "SomethingElse", 98), 40), ((44, "SomethingElse", 97), 30)]
请注意,相等性与散列匹配非常重要。如果他们不同意,就会出现未定义的行为。这就是为什么我不建议像在 c++20 中那样默认相等运算符的主要原因:
#ifdef __cpp_impl_three_way_comparison
auto operator<=>(STInfo const&) const = default;
#endif
这使得 hash_value
需要与成员达成一致并冒着他们不同步的风险变得不那么明确,例如添加一个成员。
我有一个向量,其中包含名为 ST_ThepInfo 的信息。
我的问题是在 struct Infovalue_t.
中使用 struct ST_ThepInfostruct ST_ThepInfo
{
int length;
string ex;
int weight;
};
struct Infovalue_t {
ST_ThepInfo s;
int i;
};
struct ST_ThepInfo_tag {};
typedef boost::multi_index_container<
Infovalue_t,
boost::multi_index::indexed_by<
boost::multi_index::random_access<>, // this index represents insertion order
boost::multi_index::hashed_unique<
boost::multi_index::tag<ST_ThepInfo_tag>,
boost::multi_index::member<Infovalue_t, ST_ThepInfo,&Infovalue_t::s>>
>
> myvalues_t;
然后我调用这些代码:
myvalues_t s;
ST_ThepInfo k;
....
auto t = count.emplaceback(k, 0);
但是我得到这样的错误:
我该如何解决?
散列索引要求键类型是可散列的并且equality-comparable。
您需要为信息结构提供这些:
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index_container.hpp>
namespace bmi = boost::multi_index;
struct STInfo {
int length;
std::string ex;
int weight;
auto key_fields() const { return std::tie(length, ex, weight); }
friend size_t hash_value(STInfo const& info) {
using boost::hash_value;
return hash_value(info.key_fields());
}
bool operator==(STInfo const& other) const {
return key_fields() == other.key_fields();
}
};
struct Infovalue_t {
STInfo s;
int i;
};
using Table = bmi::multi_index_container< //
Infovalue_t, //
bmi::indexed_by< //
bmi::random_access<>, // represents insertion order
bmi::hashed_unique< //
bmi::tag<struct byInfo>, //
bmi::member<Infovalue_t, STInfo, &Infovalue_t::s>> //
>>;
#include <fmt/ranges.h>
#include <fmt/ostream.h>
struct Format : fmt::formatter<int> {
auto format(STInfo const& info, auto& ctx) const {
return fmt::format_to(ctx.out(), "{}", info.key_fields());
}
auto format(Infovalue_t const& iv, auto& ctx) const {
return fmt::format_to(ctx.out(), "({}, {})", iv.s, iv.i);
}
};
template<> struct fmt::formatter<Infovalue_t> : Format{};
template<> struct fmt::formatter<STInfo> : Format{};
int main() {
Table count;
STInfo k;
count.push_back({STInfo{42, "LtUaE", 99}, 30});
count.push_back({STInfo{43, "SomethingElse", 98}, 40});
count.push_back({STInfo{44, "SomethingElse", 97}, 30});
fmt::print("{}\n", count);
}
打印:
[((42, "LtUaE", 99), 30), ((43, "SomethingElse", 98), 40), ((44, "SomethingElse", 97), 30)]
请注意,相等性与散列匹配非常重要。如果他们不同意,就会出现未定义的行为。这就是为什么我不建议像在 c++20 中那样默认相等运算符的主要原因:
#ifdef __cpp_impl_three_way_comparison
auto operator<=>(STInfo const&) const = default;
#endif
这使得 hash_value
需要与成员达成一致并冒着他们不同步的风险变得不那么明确,例如添加一个成员。