You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++14下Boost Multi Index模板类索引转标签与遍历实现问询

Alright, let's tackle this problem step by step. You're working with a template class CrMultiIndex wrapping a Boost Multi Index container (your GlobalHash type), and need to map index positions to human-readable tags, plus iterate over all indexes during initialization in C++14. Here's how to pull this off:

1. Core Approach: Compile-Time Index Traversal

Boost Multi Index containers expose a static member n_indices that tells you how many indexes are defined. We can use compile-time index sequences (via Boost's utilities, since C++14 doesn't have std::index_sequence in the standard library) to iterate over each index position, then capture its type information to generate tags.

2. Implementing the Tag Collection

First, we'll add a member to store our index tags, then write a helper function to populate it during initialization. We'll also use Boost.TypeIndex instead of raw typeid to get more readable, compiler-agnostic type names (though you can use typeid if you don't mind mangled strings).

Here's the full implementation:

#include <vector>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/type_index.hpp>
#include <boost/utility/index_sequence.hpp>

template <typename GlobalHash>
class CrMultiIndex {
private:
    GlobalHash container_;
    std::vector<std::string> index_tags_;

    // Helper to collect tags using compile-time index sequence
    template <std::size_t... Indexes>
    void collect_index_tags(boost::index_sequence<Indexes...>) {
        index_tags_.reserve(GlobalHash::n_indices);
        // Use a dummy array to expand the parameter pack in C++14
        using swallow = int[];
        (void)swallow{0, (
            // Capture readable type name for each index
            index_tags_.push_back(
                boost::typeindex::type_id<typename GlobalHash::template nth_index<Indexes>::type>()
                .pretty_name()
            ),
            0
        )...};
    }

public:
    // Initialize tags in constructor
    CrMultiIndex() {
        collect_index_tags(boost::make_index_sequence<GlobalHash::n_indices>{});
    }

    // Or use an Init function if you need delayed initialization
    void Init() {
        index_tags_.clear();
        collect_index_tags(boost::make_index_sequence<GlobalHash::n_indices>{});
    }

    // Map index number to tag string
    const std::string& n_to_tag(std::size_t index) const {
        static const std::string empty_tag = "";
        if (index >= index_tags_.size()) {
            return empty_tag; // Handle out-of-bounds gracefully
        }
        return index_tags_[index];
    }

    // Access the underlying container if needed
    GlobalHash& get_container() { return container_; }
    const GlobalHash& get_container() const { return container_; }
};

3. Alternative: Using Boost.MPL for Traversal

If you prefer using Boost.MPL instead of index sequences, you can achieve the same result with boost::mpl::for_each to iterate over index positions:

#include <boost/mpl/for_each.hpp>
#include <boost/mpl/range_c.hpp>

// Inside CrMultiIndex's private section:
struct IndexTagCollector {
    std::vector<std::string>& tags;

    explicit IndexTagCollector(std::vector<std::string>& t) : tags(t) {}

    template <std::size_t N>
    void operator()(boost::mpl::integral_c<std::size_t, N>) const {
        using IndexType = typename GlobalHash::template nth_index<N>::type;
        tags.push_back(
            boost::typeindex::type_id<IndexType>().pretty_name()
        );
    }
};

// Update collect_index_tags:
void collect_index_tags() {
    index_tags_.reserve(GlobalHash::n_indices);
    boost::mpl::for_each<boost::mpl::range_c<std::size_t, 0, GlobalHash::n_indices>>(
        IndexTagCollector{index_tags_}
    );
}

Key Notes

  • GlobalHash::n_indices: This is a static member provided by Boost Multi Index containers, giving you the total number of indexes at compile time.
  • Type Name Readability: Raw typeid(T).name() returns compiler-mangled strings (e.g., N5boost11multi_index...). Boost.TypeIndex's pretty_name() converts this to human-readable text like boost::multi_index::hashed_unique<...>.
  • Error Handling: The n_to_tag function returns an empty string for out-of-bounds indexes—adjust this to throw an exception or handle errors as needed for your use case.

内容的提问来源于stack exchange,提问作者yaron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:19:35