I’ve recently started coding in C++ and i’m having doubts about the following code. I’m having trouble with the ‘throw’ keyword. In the median or grade function when will it give an error? What is the exact usage of throw and domain_error? Will i ever get the error message from the grade or median function?
#include<iostream>
#include<string>
#include<vector>
#include<iomanip>
#include<ios>
#include<algorithm>
#include<stdexcept>
using std::cout; using std::cin;
using std::vector; using std::endl;
using std::string; using std::streamsize;
using std::setprecision; using std::domain_error;
using std::istream;
double grade(double midterm, double final, double homework)
{
return 0.2*midterm+0.4*final+0.4*homework;
}
double median(vector<double> vec)
{
typedef vector<double>::size_type vec_sz;
vec_sz size= vec.size();
if(size==0)
{
throw domain_error("Median of an empty vector"); //when will i get this error msg??
}
sort(vec.begin(),vec.end());
vec_sz mid=size/2;
return size%2==0?(vec[mid]+vec[mid-1])/2:vec[mid];
}
double grade(double midterm, double final, const vector<double>& hw)
{
if(hw.size()==0)
{
throw domain_error("Student has done no homework");// when will i get this error?
}
return grade(midterm, final, median(hw));
}
istream& read_hw(istream& in, vector<double>& hw)
{
if(in)
{
hw.clear();
double x;
while(in>>x)
hw.push_back(x);
in.clear();
}
return in;
}
int main()
{
string name;
cout<<"Please enter your name:";
cin>>name;
cout<<"Hello "<<name<<"!"<<endl;
cout << "Please enter your midterm and final exam grades: ";
double midterm, final;
cin >> midterm >> final;
cout << "Enter all your homework grades, "
"followed by end-of-file: ";
vector<double> homework;
read_hw(cin, homework);
try {
double final_grade = grade(midterm, final, homework);
streamsize prec = cout.precision();
cout << "Your final grade is " << setprecision(3)
<< final_grade << setprecision(prec) << endl;
} catch (domain_error) {
cout << endl << "You must enter your grades. "
"Please try again." << endl;
return 1;
}
return 0;
}
Imagine a series of functions calling each other:
If
Gthrows an exception of typeX, andDis the closest function that catches an exception of typeX, or one of its parents, or..., then the functionsG,FandEwill be closed andDwill catch the exception.In your case, both exceptions will be caught by
main:In the body of this catcher however, you don’t do much useful:
First of all, you are not printing the actual message that was thrown with
domain_error. See Bo Persson‘s answer for that.Second, if you want to try again, you should put the whole main in a loop, and instead of
return, youcontinue.Finally, don’t think of exceptions as a shiny great way of error handling, they are not so great.