【发布时间】:2015-11-17 23:58:08
【问题描述】:
这个程序的目的是读入数据,然后根据一些标准打印出排序的数据。
当我输入 g++ -std=c++11 -o testexe assign4.cc amenity.cc 时,我可以让我的程序编译并打印出数据,但是当我创建一个 make 文件来做同样的事情时,它会给出这些错误:
z1755294@hopper:~/assign4$ make
g++ -c amenity.cc
amenity.cc: In function ‘std::istream& operator>>(std::istream&, Amenity&)’:
amenity.cc:52:21: error: ‘stoi’ was not declared in this scope
am.id = stoi(tmp); // from_string_to< int >(tmp);
^
amenity.cc:61:31: error: ‘stof’ was not declared in this scope
am.avg_Jan_temp = stof(tmp); // from_string_to< float >(tmp);
^
amenity.cc: In function ‘float get_avg(const ListFlt&)’:
amenity.cc:176:24: warning: lambda expressions only available with -std=c++11 or -std=gnu++11
{ return init += val; });
^
amenity.cc:176:25: error: no matching function for call to ‘accumulate(std::vector<float>::const_iterator, std::vector<float>::const_iterator, double&, get_avg(const ListFlt&)::<lambda(double&, float)>)’
{ return init += val; });
^
amenity.cc:176:25: note: candidates are:
In file included from /usr/include/c++/4.9/numeric:62:0,
from Amenity.h:10,
from amenity.cc:1:
/usr/include/c++/4.9/bits/stl_numeric.h:146:5: note: template<class _InputIterator, class _Tp, class _BinaryOperation> _Tp std::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation)
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
^
/usr/include/c++/4.9/bits/stl_numeric.h:146:5: note: template argument deduction/substitution failed:
amenity.cc: In substitution of ‘template<class _InputIterator, class _Tp, class _BinaryOperation> _Tp std::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation) [with _InputIterator = __gnu_cxx::__normal_iterator<const float*, std::vector<float> >; _Tp = double; _BinaryOperation = get_avg(const ListFlt&)::<lambda(double&, float)>]’:
amenity.cc:176:25: required from here
amenity.cc:176:25: error: template argument for ‘template<class _InputIterator, class _Tp, class _BinaryOperation> _Tp std::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation)’ uses local type ‘get_avg(const ListFlt&)::<lambda(double&, float)>’
{ return init += val; });
^
amenity.cc:176:25: error: trying to instantiate ‘template<class _InputIterator, class _Tp, class _BinaryOperation> _Tp std::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation)’
In file included from /usr/include/c++/4.9/numeric:62:0,
from Amenity.h:10,
from amenity.cc:1:
/usr/include/c++/4.9/bits/stl_numeric.h:120:5: note: template<class _InputIterator, class _Tp> _Tp std::accumulate(_InputIterator, _InputIterator, _Tp)
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
^
/usr/include/c++/4.9/bits/stl_numeric.h:120:5: note: template argument deduction/substitution failed:
amenity.cc:176:25: note: candidate expects 3 arguments, 4 provided
{ return init += val; });
^
amenity.cc: In function ‘float get_sd(const ListFlt&, float)’:
amenity.cc:188:44: warning: lambda expressions only available with -std=c++11 or -std=gnu++11
{ return init += (val - avg)*(val - avg); });
^
amenity.cc:188:45: error: no matching function for call to ‘accumulate(std::vector<float>::const_iterator, std::vector<float>::const_iterator, float&, get_sd(const ListFlt&, float)::<lambda(float&, float)>)’
{ return init += (val - avg)*(val - avg); });
^
amenity.cc:188:45: note: candidates are:
In file included from /usr/include/c++/4.9/numeric:62:0,
from Amenity.h:10,
from amenity.cc:1:
/usr/include/c++/4.9/bits/stl_numeric.h:146:5: note: template<class _InputIterator, class _Tp, class _BinaryOperation> _Tp std::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation)
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
^
/usr/include/c++/4.9/bits/stl_numeric.h:146:5: note: template argument deduction/substitution failed:
amenity.cc: In substitution of ‘template<class _InputIterator, class _Tp, class _BinaryOperation> _Tp std::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation) [with _InputIterator = __gnu_cxx::__normal_iterator<const float*, std::vector<float> >; _Tp = float; _BinaryOperation = get_sd(const ListFlt&, float)::<lambda(float&, float)>]’:
amenity.cc:188:45: required from here
amenity.cc:188:45: error: template argument for ‘template<class _InputIterator, class _Tp, class _BinaryOperation> _Tp std::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation)’ uses local type ‘get_sd(const ListFlt&, float)::<lambda(float&, float)>’
{ return init += (val - avg)*(val - avg); });
^
amenity.cc:188:45: error: trying to instantiate ‘template<class _InputIterator, class _Tp, class _BinaryOperation> _Tp std::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation)’
In file included from /usr/include/c++/4.9/numeric:62:0,
from Amenity.h:10,
from amenity.cc:1:
/usr/include/c++/4.9/bits/stl_numeric.h:120:5: note: template<class _InputIterator, class _Tp> _Tp std::accumulate(_InputIterator, _InputIterator, _Tp)
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
^
/usr/include/c++/4.9/bits/stl_numeric.h:120:5: note: template argument deduction/substitution failed:
amenity.cc:188:45: note: candidate expects 3 arguments, 4 provided
{ return init += (val - avg)*(val - avg); });
^
amenity.cc: In function ‘void print_top_bottom_n(ListA&, int, int)’:
amenity.cc:257:19: error: ISO C++ forbids declaration of ‘am’ with no type [-fpermissive]
for (const auto &am : vecA)
^
amenity.cc:257:24: error: range-based ‘for’ loops are not allowed in C++98 mode
for (const auto &am : vecA)
^
amenity.cc:262:10: error: no match for call to ‘(PrintIt) (const int&)’
prt(am);
^
In file included from amenity.cc:1:0:
Amenity.h:69:7: note: candidate is:
class PrintIt
^
amenity.cc:195:6: note: void PrintIt::operator()(const Amenity&)
void PrintIt::operator () (const Amenity& am)
^
amenity.cc:195:6: note: no known conversion for argument 1 from ‘const int’ to ‘const Amenity&’
amenity.cc:270:10: error: no match for call to ‘(PrintIt) (const int&)’
prt(am);
^
In file included from amenity.cc:1:0:
Amenity.h:69:7: note: candidate is:
class PrintIt
^
amenity.cc:195:6: note: void PrintIt::operator()(const Amenity&)
void PrintIt::operator () (const Amenity& am)
^
amenity.cc:195:6: note: no known conversion for argument 1 from ‘const int’ to ‘const Amenity&’
Makefile:19: recipe for target 'amenity.o' failed
make: *** [amenity.o] Error 1
我已经附上了我的源代码和头文件。
assign4.cc
#include "Amenity.h" //include iostream and string //
#include <fstream>
using std::string;
using std::cout;
using std::cin;
using std::ifstream;
using std::flush;
using std::cerr;
string takeInString( const string& msg = "" )
{
string val;
cout << msg << flush;
getline( cin, val );
return val;
}
int takeInChr( const string& msg = "" )
{
string reply = takeInString( msg );
if( reply.size() )
return reply[0];
// else ...
return 0;
}
bool more() //open more files //
{
if( tolower( takeInChr( "Do you want to open another file (y/n) ? " )) == 'n' )
return false;
// else ...
return true;
}
bool load_from( const char* fname, ListA& vec )
{
ifstream fin( fname );
if( fin )
{
Amenity tmp;
while( fin >> tmp )
vec.push_back( tmp );
fin.close();
return true;
}
// else
cerr << "There was a problem opening file " << fname
<< endl;
cin.get();
return false;
}
int main()
{
do
{
string name = takeInString( "Enter file name: " );
// attempt to find and open file to read it ... //
ListA vecA;
if( load_from(name.c_str(), vecA) )
{
cout << "There were " << vecA.size()
<< " records in file " << name
<< '\n';
cout << "Setting scores ... " << flush;
set_scores( vecA );
cout << "done!\n";
for( int choice = 1; choice <= 7; ++ choice )
print_top_bottom_n( vecA, choice, 10 );
}
}
while( more() );
}
amenity.cc
#include "Amenity.h"
using std::cout;
using std::string;
using std::istream;
using std::istringstream;
using std::ostream;
using std::accumulate;
const string Amenity::HEADERS[] =
{
"",
"Avg January Temperature (F)", "Avg Total January Sunshine (Hours)",
"Avg July Temperature (F)", "Avg July Humidity (%)",
"Avg Landform Topo Code 1 to 21", "Area Land Next to Water (%)",
"Composite Score"
};
// default ctor //
Amenity::Amenity() : id(-1),
avg_Jan_temp(-999), avg_hrs_tot_Jan_sun(-999),
avg_Jul_temp(-999), avg_Jul_humidity(-999),
avg_landform_topo_code_1_21(-1), percent_area_next_to_water(-999),
score(0) {}
string Amenity::get_state() const { return state; }
string Amenity::get_county() const { return county; }
float Amenity::get_avg_Jan_temp() const { return avg_Jan_temp; }
float Amenity::get_avg_hrs_tot_Jan_sun() const { return avg_hrs_tot_Jan_sun; }
float Amenity::get_avg_Jul_temp() const { return avg_Jul_temp; }
float Amenity::get_avg_Jul_humidity() const { return avg_Jul_humidity; }
int Amenity::get_avg_landform_topo_code_1_21() const { return avg_landform_topo_code_1_21; }
float Amenity::get_percent_area_next_to_water() const { return percent_area_next_to_water; }
float Amenity::get_score() const { return score; }
// definition of overload operator >> for Amenity objects ...
istream& operator >> (istream& is, Amenity& am)
{
string line;
getline(is, line);
istringstream iss(line);
for (int i = 0; i < 9; ++i)
{
string tmp;
if (getline(iss, tmp, ',')) // file here is COMMA separated, 22 fields on a line //
{
switch (i) // picking off the fields of interest //
{
case 0:
am.id = stoi(tmp); // from_string_to< int >(tmp);
break;
case 1:
am.state = tmp;
break;
case 2:
am.county = tmp;
break;
case 3:
am.avg_Jan_temp = stof(tmp); // from_string_to< float >(tmp);
break;
case 4:
am.avg_hrs_tot_Jan_sun = stof(tmp); // from_string_to< float >(tmp);
break;
case 5:
am.avg_Jul_temp = stof(tmp); // from_string_to< float >(tmp);
break;
case 6:
am.avg_Jul_humidity = stof(tmp); // from_string_to< float >(tmp);
break;
case 7:
am.avg_landform_topo_code_1_21 = stoi(tmp); // from_string_to< int >(tmp);
break;
case 8:
am.percent_area_next_to_water = stof(tmp); // from_string_to< float >(tmp);
}
}
}
return is;
}
// definition of overload operator << for Amenity objects ...
ostream& operator << (ostream& os, const Amenity& am)
{
return os << am.id << ", " << am.state << ", " << am.county << ", "
<< am.avg_Jan_temp << ", " << am.avg_hrs_tot_Jan_sun << ", "
<< am.avg_Jul_temp << ", " << am.avg_Jul_humidity << ", "
<< am.avg_landform_topo_code_1_21 << ", " << am.percent_area_next_to_water;
}
// HIGHER is 'better' ...
bool cmpJanTemp(const Amenity& a, const Amenity& b)
{
return b.get_avg_Jan_temp() < a.get_avg_Jan_temp();
}
bool cmpJanSunHrs(const Amenity& a, const Amenity& b)
{
return b.get_avg_hrs_tot_Jan_sun() < a.get_avg_hrs_tot_Jan_sun();
}
// LOWER is better ...
bool cmpJulTemp(const Amenity& a, const Amenity& b)
{
return a.get_avg_Jul_temp() < b.get_avg_Jul_temp();
}
bool cmpJulHumidity(const Amenity& a, const Amenity& b)
{
return a.get_avg_Jul_humidity() < b.get_avg_Jul_humidity();
}
// HIGHER is 'better' ...
bool cmpTopoCode(const Amenity& a, const Amenity& b)
{
return b.get_avg_landform_topo_code_1_21() < a.get_avg_landform_topo_code_1_21();
}
bool cmpPartNearWater(const Amenity& a, const Amenity& b)
{
return b.get_percent_area_next_to_water() < a.get_percent_area_next_to_water();
}
bool cmpScore(const Amenity& a, const Amenity& b)
{
return b.get_score() < a.get_score();
}
void fill(ListFlt& vec, const ListA& vecA, int selectCode)
{
vec.clear();
ListA::const_iterator it;
switch (selectCode)
{
case 1: for (it = vecA.begin(); it != vecA.end(); ++it)
vec.push_back(it->get_avg_Jan_temp());
break;
case 2: for (it = vecA.begin(); it != vecA.end(); ++it)
vec.push_back(it->get_avg_hrs_tot_Jan_sun());
break;
case 3: for (it = vecA.begin(); it != vecA.end(); ++it)
vec.push_back(it->get_avg_Jul_temp());
break;
case 4: for (it = vecA.begin(); it != vecA.end(); ++it)
vec.push_back(it->get_avg_Jul_humidity());
break;
case 5: for (it = vecA.begin(); it != vecA.end(); ++it)
vec.push_back(it->get_avg_landform_topo_code_1_21());
break;
case 6: for (it = vecA.begin(); it != vecA.end(); ++it)
vec.push_back(log(100 * it->get_percent_area_next_to_water()));
break;
/*
case 7: vec.push_back( it->get_score() );
break;
*/
}
}
// 1 //
float get_avg(const ListFlt& vecF)
{
if (vecF.size() < 1) return 0; // prevent divide by zero and ... //
//const double sum = accumulate( vecF.begin(), vecF.end(), 0.0 );
double init = 0.0;
const double sum = accumulate(vecF.begin(), vecF.end(), init,
[](double& init, float val)
{ return init += val; });
return (float)sum / vecF.size();
}
// 2 //
float get_sd(const ListFlt& vecF, const float avg)
{
if (vecF.size() < 2) return 0; // prevent divide by zero and ... //
float init = 0.0;
float sum_sqs = accumulate(vecF.begin(), vecF.end(), init,
[avg](float& init, float val)
{ return init += (val - avg)*(val - avg); });
return sqrt(sum_sqs / (vecF.size() - 1));
}
void PrintIt::operator () (const Amenity& am)
{
cout << am.get_county() << ' ' << am.get_state() << ' ';
switch (choice)
{
case 1: cout << am.get_avg_Jan_temp(); break;
case 2: cout << am.get_avg_hrs_tot_Jan_sun(); break;
case 3: cout << am.get_avg_Jan_temp(); break;
case 4: cout << am.get_avg_Jul_humidity(); break;
case 5: cout << am.get_avg_landform_topo_code_1_21(); break;
case 6: cout << am.get_percent_area_next_to_water(); break;
case 7: cout << am.get_score(); break;
}
cout << '\n';
}
void set_scores(ListA& vecA)
{
float avgs[6] = { 0 }, sds[6] = { 0 };
ListFlt vecF;
for (int i = 0; i < 6; ++i)
{
fill(vecF, vecA, i + 1);
avgs[i] = get_avg(vecF);
sds[i] = get_sd(vecF, avgs[i]);
}
for (size_t i = 0; i < vecA.size(); ++i)
{
float sc = 0;
sc += (vecA[i].get_avg_Jan_temp() - avgs[0]) / sds[0];
sc += (vecA[i].get_avg_hrs_tot_Jan_sun() - avgs[1]) / sds[1];
sc += (vecA[i].get_avg_Jul_temp() - avgs[2]) / sds[2];
sc += (vecA[i].get_avg_Jul_humidity() - avgs[3]) / sds[3];
sc += (vecA[i].get_avg_landform_topo_code_1_21() - avgs[4]) / sds[4];
sc += (log(100 * vecA[i].get_percent_area_next_to_water()) - avgs[5]) / sds[5];
vecA[i].set_score(sc);
}
}
void print_top_bottom_n(ListA& vecA, int choice, int n)
{
cout << '\n' << Amenity::HEADERS[choice] << '\n';
cout << string(Amenity::HEADERS[choice].size(), '=') << '\n';
switch (choice)
{
case 1: sort(vecA.begin(), vecA.end(), cmpJanTemp); break;
case 2: sort(vecA.begin(), vecA.end(), cmpJanSunHrs); break;
case 3: sort(vecA.begin(), vecA.end(), cmpJulTemp); break;
case 4: sort(vecA.begin(), vecA.end(), cmpJulHumidity); break;
case 5: sort(vecA.begin(), vecA.end(), cmpTopoCode); break;
case 6: sort(vecA.begin(), vecA.end(), cmpPartNearWater); break;
case 7: sort(vecA.begin(), vecA.end(), cmpScore); break;
}
int count = 0,
size = vecA.size();
PrintIt prt(choice); // call ctor ... //
for (const auto &am : vecA)
{
++count;
if (count <= n)
{
prt(am);
if (count == n)
{
cout << "...\n";
}
}
else if (count > size - n)
prt(am);
}
}
Amenity.h
#ifndef AMENITY_H
#define AMENITY_H
#include <iostream>
#include <string>
#include <sstream> // re. stringstream
#include <vector>
#include <algorithm> // re. vector sort //
#include <numeric> // re. accumulate //
#include <cmath> // re. sqrt //
using std::vector;
using std::string;
using std::istream;
using std::ostream;
class Amenity
{
public:
Amenity(); // default ctor //
string get_state() const;
string get_county() const;
float get_avg_Jan_temp() const;
float get_avg_hrs_tot_Jan_sun() const;
float get_avg_Jul_temp() const;
float get_avg_Jul_humidity() const;
int get_avg_landform_topo_code_1_21() const;
float get_percent_area_next_to_water() const;
float get_score() const;
void set_score(float sc) { score = sc; }
static const string HEADERS[];
private:
int id;
string state; // 2 chars's //
string county;
float avg_Jan_temp;
float avg_hrs_tot_Jan_sun;
float avg_Jul_temp;
float avg_Jul_humidity;
int avg_landform_topo_code_1_21;
float percent_area_next_to_water;
float score;
// prototype for overload operator >> for Amenity objects ...
friend istream& operator >> (istream& is, Amenity& am);
// prototype for overload operator << for Amenity objects ...
friend ostream& operator << (ostream& os, const Amenity& am);
};
typedef vector< Amenity > ListA;
typedef vector< float > ListFlt;
bool cmpJanTemp(const Amenity& a, const Amenity& b);
bool cmpJanSunHrs(const Amenity& a, const Amenity& b);
bool cmpJulTemp(const Amenity& a, const Amenity& b);
bool cmpJulHumidity(const Amenity& a, const Amenity& b);
bool cmpTopoCode(const Amenity& a, const Amenity& b);
bool cmpPartNearWater(const Amenity& a, const Amenity& b);
bool cmpScore(const Amenity& a, const Amenity& b);
class PrintIt
{
public:
PrintIt(int choice = 1) : choice(choice) {}
void set_choice(int ch) { choice = ch; }
void operator () (const Amenity& am);
private:
int choice;
};
void fill(ListFlt& vec, const ListA& vecA, int selectCode = 1);
// 1 //
float get_avg(const ListFlt& vecF);
// 2 //
float get_sd(const ListFlt& vecF, const float avg);
void set_scores(ListA& vecA);
void print_top_bottom_n(ListA& vecA, int choice, int n);
#endif //* AMENITY_H *//
生成文件
#Assign compiler variables
CC=g++
CCXFLAGS=-std=c++11
#Create object code to executable
myprog: amenity.o assign4.o
$(CC) $(CFLAGS) -o amenity.o assign4.o
#Create source code to object code
amenity.o: amenity.cc Amenity.h
$(CC) $(CLFAGS) -c amenity.cc
assign4.o: assign4.cc Amenity.h
$(CC) $(CFLAGS) -c assign4.cc
clean:
-rm *.o myprog
如果有人可以帮助我修复这些错误并修复我的 makefile 以进行编译,我将不胜感激。
谢谢
【问题讨论】:
-
从 make 输出中你可以看到它不能用
-std=c++11编译。所以 Makefile 没有做你想做的事情并且有错误,而不是你发布的那些文件。