C ++:将一对类对象插入到一个地图中

时间:2015-12-01 16:49:14

标签: c++ class object dictionary std-pair

我正在尝试插入一个包含类name_t对象作为键的映射,并将类score_t对象作为值插入。 name_t对象应该是一个字符串,而scores_t对象是一个int的向量。我在尝试时遇到错误:

map.insert(std::pair<string, vector<int> >(n.get(), s.get()));

程序代码是:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <map>
#include <functional>
#include <algorithm>
#include <numeric>
#include <iomanip>
using namespace std;

class name_t{
    public:
        void print_name(int);
        bool operator<(const name_t &rhs) const;
        void set(string first, string last);
        string get() const { return name; }
        //Add get/set functions for firstname and lastname

    private:
        string name;
        string firstname;
        string lastname;
};

void name_t::print_name(int n){
    cout << left << setw(21) << setfill('.') << name << " ";
}

bool name_t::operator<(const name_t &rhs) const{
    if(get()!=rhs.get()) return get() < rhs.get();

    return false;
}

void name_t::set(string first, string last){
    firstname = first;
    lastname = last;
    name = lastname + ", " + firstname;
}

class scores_t{
    public:
        void push_back(int);
        void compute_stats();
        void print_scores();
        vector<int> get(){ return scores; }
        //Add accessor functions for min, max, avg, n80

    private:
        vector<int> scores;
        int min;
        int max;
        int avg, n80;
};

void scores_t::push_back(int num){
    scores.push_back(num);
}

void scores_t::compute_stats(){
    vector<int>::iterator it;
    it = min_element(scores.begin(), scores.end());
    min = *it;
    it = max_element(scores.begin(), scores.end());
    max = *it;
    int init = 0;
    avg = accumulate(scores.begin(), scores.end(), init)/scores.size();
    n80 = count_if(scores.begin(), scores.end(), bind2nd(greater<int>(),80));
}

void scores_t::print_scores(){
    cout << min << " " << max << " " << avg << " " << n80;
    scores.clear();
}

int main(int argc, char* argv[]){
    name_t n;
    scores_t s;
    ifstream fin;
    string first, last;
    int num, size, bsize=0;
    string text;
    map<name_t, scores_t> map;

    fin.open(argv[1]);

    while(getline(fin, text)){
        stringstream ss(text);
        while(ss >> first >> last){
            n.set(first, last);
            size = first.size() + last.size();
            if(size > bsize){
                bsize = size;
            }
            n.print_name(bsize);
            while(ss >> num){
                cout << num << " ";
                s.push_back(num);
            }
            cout << ": ";
            s.compute_stats();
            map.insert(std::pair<string, vector<int> >(n.get(), s.get()));
            s.print_scores();
        }
        cout << endl;
    }

    fin.close();
    return 0;
}

我收到了这些错误:

In file included from /usr/include/c++/4.8.2/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/4.8.2/bits/char_traits.h:39,
                 from /usr/include/c++/4.8.2/ios:40,
                 from /usr/include/c++/4.8.2/ostream:38,
                 from /usr/include/c++/4.8.2/iostream:39,
                 from Labstats1.cpp:1:
/usr/include/c++/4.8.2/bits/stl_pair.h: In instantiation of ‘std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U1 = std::basic_string<char>; _U2 = std::vector<int>; _T1 = const name_t; _T2 = scores_t]’:
Labstats1.cpp:106:64:   required from here
/usr/include/c++/4.8.2/bits/stl_pair.h:119:39: error: no matching function for call to ‘name_t::name_t(const std::basic_string<char>&)’
  : first(__p.first), second(__p.second) { }
                                       ^
/usr/include/c++/4.8.2/bits/stl_pair.h:119:39: note: candidates are:
Labstats1.cpp:13:7: note: name_t::name_t()
 class name_t{
       ^
Labstats1.cpp:13:7: note:   candidate expects 0 arguments, 1 provided
Labstats1.cpp:13:7: note: name_t::name_t(const name_t&)
Labstats1.cpp:13:7: note:   no known conversion for argument 1 from ‘const std::basic_string<char>’ to ‘const name_t&’
In file included from /usr/include/c++/4.8.2/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/4.8.2/bits/char_traits.h:39,
                 from /usr/include/c++/4.8.2/ios:40,
                 from /usr/include/c++/4.8.2/ostream:38,
                 from /usr/include/c++/4.8.2/iostream:39,
                 from Labstats1.cpp:1:
/usr/include/c++/4.8.2/bits/stl_pair.h:119:39: error: no matching function for call to ‘scores_t::scores_t(const std::vector<int>&)’
  : first(__p.first), second(__p.second) { }
                                       ^
/usr/include/c++/4.8.2/bits/stl_pair.h:119:39: note: candidates are:
Labstats1.cpp:43:7: note: scores_t::scores_t()
 class scores_t{
       ^
Labstats1.cpp:43:7: note:   candidate expects 0 arguments, 1 provided
Labstats1.cpp:43:7: note: scores_t::scores_t(const scores_t&)
Labstats1.cpp:43:7: note:   no known conversion for argument 1 from ‘const std::vector<int>’ to ‘const scores_t&’

我不太清楚这些错误是什么意思。任何帮助表示赞赏。谢谢!

1 个答案:

答案 0 :(得分:2)

您的地图数据类型为std::pair<name_t, scores_t>,但您尝试插入一对std::stringstd::vector - 因为这是您的get()函数返回的内容。

要解决立即编译错误,只需在插入时使用正确的数据类型。

但是,您的代码还有其他更微妙的问题。例如,您的get()函数按值返回成员。这意味着,每次调用函数时都会生成一个副本 - 复制矢量或字符串需要花费很多时间。相反,您应该通过返回const引用的函数公开您的成员。

此外,对于包装类(您的类本质上是包装器)来说,定义构造函数是一个很好的做法,它将采用包装类型的参数。例如,对于您的name_t,您可能需要如下构造函数:

name_t::name_t(const std::string& name) : name(name) {}