无法迭代boost无序哈希映射

Unable to iterate through boost unordered hashmap

本文关键字:哈希 映射 无序 boost 迭代      更新时间:2023-10-16

我正在使用boost无序哈希表,我很难循环遍历哈希表中的所有键。

#include <vector>
#include <iostream>
#include <boost/unordered_map.hpp>
#include <boost/foreach.hpp>
struct Record
{
        char *data;
};
typedef boost::unordered_map<std::string, std::vector<Record*> > MAP;
struct OuterRelation
{
        short num_keys;
        short join_key_ndx;
        MAP hash_table;
};

Record *new_record = malloc(sizeof(Record));
new_record->data = "some string";
char *key = new_record->data;
(outer_relation->hash_table)[key].push_back(new_record);
/* print all keys in the hash table */
BOOST_FOREACH(MAP::value_type pair, outer_relation->hash_table)
{
       std::string key  = pair.first;
       ...
}

程序在foreach循环时失败。我添加到哈希表中的元素有问题吗?

由于这是c++ ,请停止使用malloc 。(c++使用newdelete。虽然:也不要用这些。使用std::make_unique,或者std::make_sharedstd::vector<T>)。


说到这里,原因如下:C没有类。C只有pod类型struct s。

只要你在c++代码中保证这一点,你就可以"摆脱"C-isms。下面是一个c++泛型函数,它通过检查:

来实现malloc技巧
template <typename T, typename... Args>
T* make_memory_leak(Args&&... args) {
    static_assert(std::is_pod<T>::value, "undefined behaviour for non-POD types");
    T* raw = static_cast<T*>(malloc(sizeof(T)));
    static_assert(boost::proto::is_aggregate<T>::value, "aggregate initialization required");
    *raw = { std::forward<Args>(args)... };
    return raw;
}

现在你可以直接写

auto record_ptr = make_memory_leak<Record>("some string");

等价
Record* record_ptr = static_cast<Record*>(malloc(sizeof(Record)));
*record_ptr = { "some string" }; // aggregate initialization
所以,这是你的测试代码,工作:Live on Coliru
#include <vector>
#include <iostream>
#include <boost/unordered_map.hpp>
#include <boost/foreach.hpp>
#include <boost/proto/traits.hpp>
#include <cstdlib>
struct Record {
    char const* data;
};
typedef boost::unordered_map<std::string, std::vector<Record*> > MAP;
struct OuterRelation
{
    short num_keys;
    short join_key_ndx;
    MAP hash_table;
};
template <typename T, typename... Args>
T* make_memory_leak(Args&&... args) {
    static_assert(std::is_pod<T>::value, "undefined behaviour for non-POD types");
    T* raw = static_cast<T*>(malloc(sizeof(T)));
    static_assert(boost::proto::is_aggregate<T>::value, "aggregate initialization required");
    *raw = { std::forward<Args>(args)... };
    return raw;
}
int main()
{
    auto outer_relation = std::make_shared<OuterRelation>();
    for (auto key : { "some string", "some other string", "which", "by the way", "are", "const char(&)[]" })
        outer_relation->hash_table[key].push_back(make_memory_leak<Record>(key));
    /* print all keys in the hash table */
    BOOST_FOREACH(MAP::value_type pair, outer_relation->hash_table)
    {
        std::cout << pair.first << "n";
    }
}