[英]Unordered_map of unordered_map vs custom hash function for pair key C++?
[英]C++ unordered_map with custom key resulting in null values
我正在使用带有Currency
键的std::unordered_map
和具有货币价格double
的值。 Currency
是我制作的自定义类。 这是我尝试过的一个版本:
#ifndef CURRENCY_H
#define CURRENCY_H
#include "Nameable.h"
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/functional/hash.hpp>
#include "BigDecimal.h"
#include <iostream>
/**
* Represents a single currency. Can be used as keys in a map and as a general
* identifier for determining what unit a value of money is.
* @param name
*/
class Currency: public Nameable {
public:
Currency(std::string name) throw(NameAlreadyTakenException);
Currency(const Currency& orig);
virtual ~Currency();
virtual std::string getName();
virtual void setName(std::string name) throw(NameAlreadyTakenException);
inline bool operator==(const Currency& key) const {
return this->id == key.id;
}
// A custom hasher that I tried using.
struct currencyHasher
{
std::size_t operator()(const Currency& k) const
{
return boost::hash<boost::uuids::uuid>()(k.id);
}
};
boost::uuids::uuid id;
private:
};
// A template specialization for Currency.
namespace std {
template <>
struct hash<Currency> {
std::size_t operator()(const Currency& k) const {
cout<< boost::hash<boost::uuids::uuid>()(k.id)<<"\n";
return boost::hash<boost::uuids::uuid>()(k.id);
}
};
}
#endif /* CURRENCY_H */
这是实现:
#include "Currency.h"
Currency::Currency(std::string name) throw(NameAlreadyTakenException) {
this->setName(name);
this->id = boost::uuids::random_generator()();
}
Currency::Currency(const Currency& orig) {
}
Currency::~Currency() {
}
std::string Currency::getName() {
return this->name;
}
void Currency::setName(std::string name) throw(NameAlreadyTakenException) {
this->name = name;
}
我通过使用自定义类类型作为键来实现C ++ unordered_map答案给出的两个建议,从而使Currency
键兼容。 如您所见,我已经覆盖了operator ==,并提供了自定义哈希器以及专门化模板。
尽管如此,这些键似乎正在丢失值。 我的意思是说,双精度数,浮点数和整数都变成0,而字符串变成空字符串。 当然,它会导致其他问题,而我将其用作值。 例如:
Currency dollar("Dollar")
std::unordered_map<Currency,int,Currency::currencyHasher> currenMap;
currenMap[dollar]=1337;
std::cout<<currenMap[dollar]<<"\n";
在控制台中,此命令的输出为0。使用模板专用化也不起作用:
std::unordered_map<Currency,int> currenMap;
currenMap[dollar]=1337;
std::cout<<currenMap[dollar]<<"\n";
也会产生一个0 ...
Currency
是Nameable
的子类的Nameable
会引起问题? 我使用boost :: uuid作为哈希值(利用boost::hash<boost::uuids::uuid>
将id转换为size_t
)我不确定我缺少什么,谢谢你的帮助。
问题出在拷贝构造函数上:
Currency::Currency(const Currency& orig) {
}
复制Currency
,您会得到一个默认构造的id
。 当您将Currency
插入地图时,它会被复制,并且该副本将具有与原始ID不同的ID。 因此:
currenMap[dollar]=1337;
有效地将{Currency(), 1337}
到地图中。 因此,当您查找具有为dollar
创建的id的对象时,它就不会在那里。 并不是说该值被“清零”了……而是您得到了默认构造的值。
修复副本构造函数应该可以解决该问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.