假设我有std::map<std::string, T>
(或unordered_map
),我想从迭代器/引用/指针访问内容。
有没有办法在没有std::string
密钥的两个副本的情况下执行此操作(一个由地图拥有,一个在内容对象内)?一个人可以引用另一个吗?
答案 0 :(得分:3)
你会考虑使用boost :: bimap吗?以下是一个简单的例子:
#include <boost/bimap.hpp>
#include <string>
struct Person
{
Person()
{}
Person(const std::string& f, const std::string& l, int a) : first(f), last(l), age(a)
{}
std::string first;
std::string last;
int age;
};
bool operator <(const Person& lhs, const Person& rhs)
{
if(lhs.last < rhs.last)
return true;
return false;
}
std::ostream& operator << (std::ostream& os, const Person& p)
{
os << "First Name: " << p.first << " Last Name: " << p.last << " Age: " << p.age;
return os;
}
int main()
{
typedef boost::bimap<std::string, Person> people;
typedef people::value_type value;
people m;
m.insert(value("12345",Person("fred", "rabbit", 10)));
m.insert(value("67890",Person("benjamin", "bunny", 12)));
Person p = m.left.at("12345");
std::cout << "Person with serial no. 12345 is: " << p << "\n";
std::cout << "Serial number of " << p << " is: " << m.right.at(p) << "\n";
}
答案 1 :(得分:2)
他们之所以这么做是因为这很危险。您必须保证,没有任何关键字std::string
成员永远不会更改值,或者整个地图都会失效。有趣的是,第一个出现在脑海中的解决方案似乎是疯狂的,而且看起来像UB一样,但我相信我非常小心地绕过UB。
struct key_type {
mutable const char* ptr;
};
bool operator<(const key_type& lhs, const key_type& rhs)
{return strcmp(lhs.ptr, rhs.ptr)<0;}
struct person {
std::string name;
int age;
};
person& people_map_get(std::map<key_type, person>& map, const char* name) {
auto it = map.insert(name, person{name}).first; //grab, possibly insert
if->first.ptr = it->second.name.c_str(); //in case of insert, fix ptr
return it->second;
}
person& people_map_assign(std::map<key_type, person>& map, person p) {
auto pair = map.insert(name, p); //grab, possibly insert
auto it = pair.first;
if (pair.second == false)
it->second = std::move(p);
if->first.ptr = it->second.name.c_str(); //ptr probably invalidated, so update it
return it->second;
}
int main() {
std::map<key_type, person> people;
people_map_assign(people, person{"ted"});
person frank = people_map_get(people, "frank");
}
我希望很清楚,这是疯狂接近UB,非常不推荐。基本上,在插入/查找期间,关键点指向临时对象或输入字符串,然后一旦插入/找到对象,键就会更改为指向字符串成员中包含的值,并且只要你永远不会做任何会使任何包含.c_str()
对象的person
的返回值无效的事情,一切都勉强起作用。我想。
答案 2 :(得分:1)
为什么不创建两个对象:
std::set<std::string> wordSet;
std::map<std::string*, T> yourMap;
T必须包含指向std :: string的指针,而yourMap需要自定义比较器。此外,您可以将所有这些包装在某个类中。
答案 3 :(得分:-1)
两者都可以是对相同值的引用。例如:
#include <stdio.h>
#include <string>
#include <map>
struct xx { std::string mykey; int value; };
int main (int argc, char **argv)
{
std::string key1("the-key");
std::map<std::string, xx> map;
map[key1].mykey = key1;
map[key1].value = 13;
std::string &lookup_key = map[key1].mykey;
printf("%d\n", map[lookup_key].value);
}