【问题标题】:How do I make a multimap with objects? - C++如何使用对象制作多图? - C++
【发布时间】:2020-06-08 06:18:41
【问题描述】:

所以我有一个 Date 类,每个 Date 对象都存储该对象的日、月和年变量。我还有一个数据文件,其中包含多个日期、许多重复日期,并且都有自己的浮点值。

我正在尝试将我所有的日期作为键存储到一个多地图中,这样我也可以将所有重复的日期及其浮点数都存储在其中。我的目标是,我希望用户能够输入月份和年份,然后我在地图中搜索日期对象中具有该月份和年份的值,并返回这些对象的速度。但是,我收到此错误:

 error: no matching function for call to 'make_pair(Date&, float)'|

为此声明

mapOption1.insert(make_pair<Date, float>(windlog[x].d, windlog[x].speed.GetSpeed()));

我不明白为什么,当我在二叉搜索树中使用 windlog[x].d(其中 windlog 是结构的向量,d 是它在位置 x 处保存的日期对象)时,我没有需要一个 Get 方法来将对象存储在 BST 中。为什么我现在需要它?假设这是问题所在。

这是我的问题的代码:

multimap<Date, float> mapOption1;

    for(int x = 0; x < SIZE; x++)
    {
        mapOption1.insert(make_pair<Date, float>(windlog[x].d, windlog[x].speed.GetSpeed()));
    }

最小的可重现示例:

multimap<Date, float> mapOption1;

    Date datetest;
    datetest.SetDay("20");
    datetest.SetMonth("3");
    datetest.SetYear("2014");

    for(int x = 0; x < SIZE; x++)
    {
        mapOption1.insert(make_pair<Date, float>(datetest, 47.5);
    }

日期.h:

#if !defined(_DATE_H)
#define _DATE_H

#include <iostream>
#include <string>
#include <tuple>

using namespace std;

    /**
     * @class Date
     * @brief  Manages and holds all dates
     *
     * This class is used to convert string from the input file into numerical values
     * and then store them as date values
     * @author Darren Fernando
     *
     * @date 05/05/2020 Darren Fernando, Started
     * @bug No bugs founds as of yet
     */
class Date
{
public:
    Date();
    Date(unsigned day1, unsigned month1, unsigned year1);

        /**
        * @brief A set method that is used to set the day value
        * It takes a string parameter and calls another method to convert it, and then assign it to the variable day
        * @param day1 - A string variable that is converted
        * @return void
        */
    void SetDay(string day1);

        /**
        * @brief A set method that is used to set the month value
        * It takes a string parameter and calls another method to convert it, and then assign it to the variable month
        * @param month1 - A string variable that is converted
        * @return void
        */
    void SetMonth(string month1);

        /**
        * @brief A set method that is used to set the year value
        * It takes a string parameter and calls another method to convert it, and then assign it to the variable year
        * @param year - A string variable that is converted
        * @return void
        */
    void SetYear(string year1);

        /**
        * @brief A get method that is used to get the day value by returning it
        * @return unsigned
        */
    unsigned GetDay() const;

        /**
        * @brief A get method that is used to get the month value by returning it
        * @return unsigned
        */
    unsigned GetMonth() const;

        /**
        * @brief A get method that is used to get the year value by returning it
        * @return unsigned
        */
    unsigned GetYear() const;

        /**
        * @brief A method that converts a string to an unsigned numerical value
        * @param time - A string parameter that is converted
        * @return unsigned
        */
    unsigned convertString(string date) const;

        /**
        * @brief A method that takes an input stream and perfoms some operations to set the date from this stream
        * This method isn't used but may be valuable later on
        * @param input - An input stream
        * @return void
        */
    void SetDate(istream &input);

        /**
        * @brief A method that takes an output stream and outputs it
        * This method isn't used but may be valuable later on
        * @param os - An output stream
        * @return void
        */
    void GetDate(ostream & os) const;
    unsigned GetDateRaw() const;

private:

    int day; /// Variable to store the day
    int month; /// Variable to store the month
    int year; /// Variable to store the year

};

bool operator==(const Date& firstDate, const Date& secondDate);
bool operator>(const Date& firstDate, const Date& secondDate);
bool operator!=(const Date& firstDate, const Date& secondDate);
ostream & operator <<(ostream & os, const Date & D); /// Operator << overload
istream & operator >>(istream & input, Date & D); /// Operator >> overload
#endif  //_DATE_H

日期.cpp:

//
//
//  Generated by StarUML(tm) C++ Add-In
#include "Date.h"

    // Default constructor
Date::Date(){}

    /* Date constructor to initialize an object of date with the passed parameters
    */
Date::Date(unsigned day1, unsigned month1, unsigned year1) {

    day = day1;
    month = month1;
    year = year1;

}

void Date::SetDay(string day1) {

    day = convertString(day1); // Calls method convertString to convert the string parameter and assign the new value to day.

}

void Date::SetMonth(string month1) {

    month = convertString(month1); // Calls method convertString to convert the string parameter and assign the new value to month.

}

void Date::SetYear(string year1) {

    year = convertString(year1); // Calls method convertString to convert the string parameter and assign the new value to year.

}

unsigned Date::GetDay() const {

    return day; // Returns the day of the object

}

unsigned Date::GetMonth() const {

    return month; // Returns the month of the object

}

unsigned Date::GetYear() const {

    return year; // Returns the year of the object

}

    /* This method is used for directly setting the date from a file. It is not used now,
    but may prove handy in the future.*/
void Date::SetDate(istream &input){

    string day1;
    string month1;
    string year1;


    getline(input, day1, '/'); //Reads line until '/' is found and stores the string in day1
    getline(input, month1, '/'); //Reads line until '/' is found and stores the string in month1
    getline(input, year1, ' '); //Reads line until ' ' is found and stores the string in year1

    /*Sets the strings with setters which convert them automatically
    */
    SetDay(day1);
    SetMonth(month1);
    SetYear(year1);


}
    //This method is designed to convert a string to an integer
inline unsigned Date::convertString(string date) const{

    int date2 = 0;

    date2 = stoi(date); //Uses stoi from cmath library to convert a string to an integer

    return date2;

}

    // A get function that uses the overloaded output stream to output the date in a specific format.
void Date::GetDate(ostream &os) const{

    os << GetDay() << "/" << GetMonth() << "/" << GetYear() << " ";

}

unsigned Date::GetDateRaw() const{

    return month && year;

}

bool operator==(const Date& firstDate, const Date& secondDate)
{
    if(firstDate.GetYear() == secondDate.GetYear() && firstDate.GetMonth() == secondDate.GetMonth() && firstDate.GetDay() == secondDate.GetDay())
    {

        return true;

    }
    else
    {
        return false;
    }

}

/*bool operator!=(const Date& firstDate, const Date& secondDate)
{
    if(firstDate!=secondDate)
    {
        return true;
    }
    return false;
}*/

bool operator>(const Date& firstDate, const Date& secondDate)
{
    if(firstDate.GetYear() > secondDate.GetYear())
    {
        return true;
    }
    if(firstDate.GetYear() == secondDate.GetYear())
    {
        if(firstDate.GetMonth() > secondDate.GetMonth())
        {
            return true;
        }
        else if(firstDate.GetMonth() == secondDate.GetMonth())
        {
            if(firstDate.GetDay() > secondDate.GetDay())
            {
                return true;
            }
        }
    }
    return false;
}

    // Input stream operator overload
istream & operator >>( istream & input, Date & D) {

    D.SetDate(input);
    return input;

}
    // Output stream operator overload
ostream & operator <<( ostream & os, const Date & D) {

    D.GetDate(os);

    return os;

}

【问题讨论】:

  • 你能发一个minimal reproducible example吗?一个小例子,我们可以复制粘贴到 ide 中并重现您的问题,而无需进行任何修改。可能和Date的定义有关。
  • 好的,谢谢。这是我们可以合作的。将来您应该更多地关注最小部分 - 例如删除所有 cmets 和未使用的函数,如 io-operators。
  • 现在给出一些答案:我想这将是一个仅链接的答案,所以这里基本上有两个相关的问题:std::make_pair 旨在自动为您推断模板参数。它不适合与显式参数一起使用,请参见此处:stackoverflow.com/a/9642232/5105949。其次,地图需要operator&lt;。您已经拥有operator&gt;,因此修复它应该很容易。参考问题:stackoverflow.com/a/1102720/5105949
  • make_pair&lt;Date, float&gt;(datetest, 47.5) 中使用显式模板参数是问题所在。不确定解释,但 make_pair(datetest, 47.5) 工作正常。 make_pair 的重点是您不必必须使用显式类型。
  • 您通过提供对 Date 的引用来调用“make_pair(Date&, float)”。在我的 VisualStudio 中,它显示它需要一个 &&,因此您应该调用 make_pair(windlog[x].d.getACopy() 之类的东西,而不是 make_pair(windlog[x].d) , 或 make_pair(Date(windlog[x].d),

标签: c++ vector maps multimap


【解决方案1】:

请检查以下代码,看看是否可以对其进行调整以获得所需的内容。 基本上,我创建了一个包含日期、月份、年份和速度成员的 Date 类。日期用作

class Date{
public:
    Date(int, int, unsigned int);
    int getDay()const {return day;};
    int getMonth()const {return month;};
    unsigned int getYear()const {return year;};
    void setSpeed(float s){ speed = s;};
    float getSpeed(){return speed;};

private:
    int day;
    int month;
    unsigned int year;
    float speed = 0;};

Date::Date(int d, int m, unsigned int y): day(d), month(m), year(y) {};

bool compareDay(const Date &a, const Date &b){
    return a.getDay() < b.getDay();
}

int main(){
    Date firstDate(23, 1, 1984);
    Date secondDate (12, 10, 2012);
    firstDate.setSpeed(20.3);
    secondDate.setSpeed(34.2);

    std::multimap<Date, float, decltype(compareDay)*> dateMap(compareDay);

    dateMap.insert({{firstDate, firstDate.getSpeed()}, {secondDate, secondDate.getSpeed()}});

for (auto i : dateMap){
    std::cout << (i.first).getDay() << "/" << (i.first).getMonth() << "/" << (i.first).getYear() << " - " << "Speed: " << (i.second) << std::endl;}

【讨论】:

    猜你喜欢
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多