无法迭代通过boost无序hashmap

时间:2014-03-08 15:45:33

标签: c++ boost

我正在使用boost无序hashmap,而且我很难在循环表中循环遍历所有键。

#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循环中失败。我正在添加到哈希表中的元素是否存在问题?

1 个答案:

答案 0 :(得分:2)

由于这是C ++ 停止使用malloc 。 (C ++使用newdelete。虽然:也不要使用它们。使用std::make_uniquestd::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";
    }
}