在C++中将用户定义的类作为键Map到其他用户定义的类[duplicate]

yvt65v4c  于 2023-01-22  发布在  其他
关注(0)|答案(1)|浏览(143)
    • 此问题在此处已有答案**:

C++ map with custom key(2个答案)
1小时前关闭。
我创建了两个类:BankAccount
我想使用std::map<Bank, Account> bankAccount,如下所示:

bankAccount.insert(std::make_pair(bank1, account1));

但是我得到了几个编译时错误。
我知道如何使用map<int, Bank>map<int, Account>,但不知道map<Bank, Account>。我假设问题在于告诉编译器如何确保我的Bank对象是唯一的,并且由于C++中的Map是有序的,我需要告诉编译器如何排序库。如果键碰巧是整数,这对编译器来说没有问题。
我的班级如下:

class Bank {
public:
    // Constructors
    Bank() = default;
    Bank(std::string name, std::string created, int balance, bool active)
            : m_name(std::move(name)), m_created(std::move(created)), m_balance(balance),   m_active(active) {};

    // Member functions
    void deposit(int amount) {
        m_balance += amount;
    }
    [[nodiscard]] int getBalance() const {
        return m_balance;
    }

    void setBalance(int amount) {
        m_balance = amount;
    }

    // Member attributes
    std::string m_name;
    std::string m_created;
    int m_balance{};
    bool m_active{};
};

class Account {
public:
    // Constructor
    Account() = default;
    Account(std::string name, int balance){
        m_name = name;
        m_balance = balance;
    }

    //Member functions
    void displayBalance() const {
        std::cout << m_name << ": " << m_balance << std::endl;
    }

    // Member attributes
    std::string m_name;
    int m_balance{};
};

银行对象的创建过程如下:

Bank bank1("FirstBank", "2015-01-01", 1000, true);

帐户对象的创建过程如下:

Account account1("Dining", 10000);

有人能告诉我如何使用Bank类作为std::map的键吗?
我尝试在Bank类中重载operator<(),如下所示,但这没有解决我的问题:

bool operator<(Bank& other) {
    return m_name < other.m_name && m_created < other.m_created \
        && m_balance < other.m_balance && m_active < other.m_active;
}

std::map切换到std::unordered_map也不能消除编译时错误。

w46czmvw

w46czmvw1#

为你的Bank类重载operator<是正确的解决方案,但是你的实现是错误的,这将导致编译时错误,更糟的是在运行时导致 * 未定义的行为 *。
试试类似这样的方法:

class Bank {
public:
    ...

    bool operator<(const Bank& other) const {
        if (m_name < other.m_name)
            return true;
        if (m_name > other.m_name)
            return false;
        // m_name and other.m_name must be equal, keep comparing...

        if (m_created < other.m_created)
            return true;
        if (m_created > other.m_created)
            return false;
        // m_created and other.m_created must be equal, keep comparing...

        if (m_balance < other.m_balance)
            return true;
        if (m_balance > other.m_balance)
            return false;
        // m_balance and other.m_balance must be equal, keep comparing...

        return m_active < other.m_active;
    }
};

或者:

class Bank {
public:
    ...
};

bool operator<(const Bank& b1, const Bank& b2)
{
    if (b1.m_name < b2.m_name)
        return true;
    // and so on, as shown above ...
}

无论哪种方式,通过将值std::tie() '在一起可以大大简化运算符的实现,因为std::tie已经实现了operator<,例如:

class Bank {
public:
    ...

    bool operator<(const Bank& other) const {
        return std::tie(m_name, m_created, m_balance, m_active) < std::tie(other.m_name, other.m_created, other.m_balance, other.m_active);
    }
}

或者:

class Bank {
public:
    ...
};

bool operator<(const Bank& b1, const Bank& b2) {
    return std::tie(b1.m_name, b1.m_created, b1.m_balance, b1.m_active) < std::tie(b2.m_name, b2.m_created, b2.m_balance, b2.m_active);
}

相关问题