1
votes

If I have an unordered map of unordered_sets indexed by strings, such as

static boost::unordered_map<std::string, boost::unordered_set<std::string> > UseMap;

I had a couple question about using this data structure. Is there anyway for me to insert a new value into the set indexed in the map without having to use a pointer to the set or reindex the map value?

Second question, I'm getting an unresolved external symbol error when I try to index into the map. As an example,

void AddUse(const std::string &character, const std::string& used)
{
    auto set = UseMap[character];
    set.insert(used);
    UseMap[character] = set;

}

I'm not sure why this is causing an unresolved symbol error, so any guidance there would be helpful.

Thanks in advance

EDIT: Any use of UseMap[character] causes the unresolved symbol error

Also added error code and source example

Full Class

#pragma once
#ifndef _SINGLEUSE_H_
#define _SINGLEUSE_H_
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include <string>
#include <vector>
class SingleUse
{
public:
    void AddUse(const std::string& character, const std::string& used)
    {
        UseMap[character].insert(used);
    }

    bool HasUsed(const std::string &character, const std::string& used)
    {
        return false;//UseMap[character].find(used) != UseMap[character].end();
    }

    void ClearAll()
    {
        UseMap.clear();
    }
private:
    static boost::unordered_map<std::string, boost::unordered_set<std::string> > UseMap;
};

And the full error message:

Error 52 error LNK2001: unresolved external symbol "private: static class boost::unordered_map,class std::allocator >,class boost::unordered_set,class std::allocator >,struct boost::hash,class std::allocator > >,struct std::equal_to,class std::allocator > >,class std::allocator,class std::allocator > > >,struct boost::hash,class std::allocator > >,struct std::equal_to,class std::allocator > >,class std::allocator,class std::allocator > const ,class boost::unordered_set,class std::allocator >,struct boost::hash,class std::allocator > >,struct std::equal_to,class std::allocator > >,class std::allocator,class std::allocator > > > > > > SingleUse::UseMap" (?UseMap@SingleUse@@0V?$unordered_map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$unordered_set@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@U?$hash@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@boost@@U?$equal_to@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@boost@@U?$hash@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@4@U?$equal_to@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$unordered_set@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@U?$hash@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@boost@@U?$equal_to@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@boost@@@std@@@2@@boost@@A) G:\Documents\Programming Projects\KHMP\KHMP_Repo\KHMP\build\KHMP\KHMP\KHMPMain.obj

2
auto set should be auto& set, 'set' is a copy...Rick
Could you tell what symbol is the problem?Bo Persson
The question still stands. Which symbol is the problem, now which statement. The error message mentions some symbol or symbols and having full text of the message including the symbol name might be an important hint to what is going on.Jan Hudec
Why do you copy the set, insert into the copy and than copy the set back in? The operator[] returns a reference, so you can simply UseMap[character].insert(used).Jan Hudec
@mgiuca: "unresolved symbol" is always a linker error.Jan Hudec

2 Answers

3
votes

First question, yes, it should be fine as long as you assign the result to a reference.

Do this:

boost::unordered_set<std::string>& set = UseMap[character];

Now set is a reference to a value in the map. (I'm not sure what auto gives you, so I put the type in full; you may be able to get away with using auto.) Any changes you make to set will be reflected in the map.

set.insert(used); // This updates the map, no need to write it back in.
1
votes

Ok, the unresolved symbol is because I don't instantiate the static variable anywhere. I forgot you had to do that in C++, my mistake. Thanks for the help with the sets