簡體   English   中英

具有自定義鍵的C ++ unordered_map導致空值

[英]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 ...

CurrencyNameable的子類的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM