C++:将成对的 class 个对象插入到地图中
C++: Inserting pairs of class objects into a map
我正在尝试插入一个包含 class name_t 对象作为键和 class scores_t 对象作为值的映射。 name_t 对象应该是一个字符串,而 scores_t 对象是一个整数向量。我在尝试执行时遇到错误:
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&’
我不太清楚这些错误是什么意思。任何帮助表示赞赏。谢谢!
您的地图数据类型是 std::pair<name_t, scores_t>
,但您试图插入一对 std::string
和 std::vector
- 因为这是您的 get()
函数returning.
要解决直接的编译错误,只需在插入时使用正确的数据类型即可。
但是,您的代码还有其他更微妙的问题。例如,您的 get()
按值函数 return 成员。这意味着,每次调用该函数时都会制作一个副本 - 复制向量或字符串需要花费相当多的时间。相反,您应该通过函数 returning const
引用公开您的成员。
此外,包装器 class(您的 classes 本质上是包装器)定义构造函数是一个很好的做法,该构造函数将采用包装类型的参数。例如,对于您的 name_t
,您可能需要如下构造函数:
name_t::name_t(const std::string& name) : name(name) {}
我正在尝试插入一个包含 class name_t 对象作为键和 class scores_t 对象作为值的映射。 name_t 对象应该是一个字符串,而 scores_t 对象是一个整数向量。我在尝试执行时遇到错误:
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&’
我不太清楚这些错误是什么意思。任何帮助表示赞赏。谢谢!
您的地图数据类型是 std::pair<name_t, scores_t>
,但您试图插入一对 std::string
和 std::vector
- 因为这是您的 get()
函数returning.
要解决直接的编译错误,只需在插入时使用正确的数据类型即可。
但是,您的代码还有其他更微妙的问题。例如,您的 get()
按值函数 return 成员。这意味着,每次调用该函数时都会制作一个副本 - 复制向量或字符串需要花费相当多的时间。相反,您应该通过函数 returning const
引用公开您的成员。
此外,包装器 class(您的 classes 本质上是包装器)定义构造函数是一个很好的做法,该构造函数将采用包装类型的参数。例如,对于您的 name_t
,您可能需要如下构造函数:
name_t::name_t(const std::string& name) : name(name) {}