undeclared identifier vs no matching function for call to...

I'm trying to compile the following code which is from a very old book (2001)

Accelerated C++ Practical Programming by Example by Andrew Koenig, Barbara E. Moo (z-lib.org)


i get either one (not both) of the following errors
A) error: no matching function for call to 'grade'
return grade(midterm, final, median(hw));

B) error: use of undeclared identifier 'median'
return grade(midterm, final, median(hw));

which error i get depends on the sequence of the two blocks
1) double median(vector<double> vec)
2) double grade(double midterm, double final, const vector<double>& hw)

i know these two sort of depend on one another to work...

could you tell me what i'm missing in here pls?


the codes are from chapter 4 (Organizing programs and data) of the book



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <algorithm>
#include <iomanip> 
#include <ios> 
#include <iostream> 
#include <string>
#include <vector>



using std::cin; 
using std::cout; 
using std::endl;
using std::setprecision; 
using std::string; 
using std::streamsize;
using std::sort; 
using std::vector;
using std::istream;
using std::domain_error;









// compute the median of a vector<double>
// note that calling this function copies the entire argument vector 

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");

		sort(vec.begin(), vec.end());
		
		vec_sz mid = size / 2;
		
		return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid]; 
		
}




// compute a student's overall grade from midterm and final exam grades
// and vector of homework grades.
// this function does not copy its argument, because median does so for us. 

double grade(double midterm, double final, const vector<double>& hw)
{
	if (hw.size() == 0)
	throw domain_error("student has done no homework");
	return grade(midterm, final, median(hw)); 
}





// read homework grades from an input stream into a vector<double> 

istream& read_hw(istream& in, vector<double>& hw)
{
	
	double x;
	
	
	if (in) {
	// get rid of previous contents hw.clear() ;
	// read homework grades double x;
	while (in >> x)
	hw.push_back(x);
	// clear the stream so that input will work for the next student
	in.clear(); 
	}

return in; 

}







int main() 
{
	// ask for and read the student's name 
	cout << "Please enter your first name: "; 
	string name;
	cin >> name;
	cout << "Hello, " << name << "!" << endl;
	
	
	
	// ask for and read the midterm and final grades
	cout << "Please enter your midterm and final exam grades: "; 
	double midterm, final;
	cin >> midterm >> final;

	// ask for the homework grades
	cout << "Enter all your homework grades, "
		"followed by end-of-file: ";


	vector<double> homework;

	// read the homework grades 
	read_hw(cin, homework);

	
	// compute and generate the final grade, if possible 
	
	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; 
		
		}
M'ok, what are the parameter types in the grade function? double, double and const std::vector.

What is the return type of the median function? double.

In the return statement in the grade function you are recursively calling grade with double, double and double. *BOMB-O!*

Regarding the book you are trying to learn from, it is VERY outdated. Released in 2000, so no C++11, forget about any later language standard.

How are you compiling these examples? What is your compiler?

You recently started learning C++, the book you chose is IMO not a good beginner's book because of how old it is.

A decent online and FREE! tutorial that teaches more modern C++, Learn C++:
https://www.learncpp.com/

If books work for you I'd suggest what I consider is a better book, Bjarne Stroustrup's "Programming: Principles and Practice Using C++ (2nd Edition)"
https://www.amazon.com/Programming-Principles-Practice-Using-2nd/dp/0321992784/
Why do I suggest Saint Bjarne's book? 'Cuz he's the guy who invented C++.

Plus the 2nd Edition of the book was released in 2014, it has C++11 language features along with a smattering of C++14.

I'd still recommend plowing your way through Learn C++. It's free, and being updated on a frequent basis with revisions up to the current C++20 language standard.

No tutorial website or single book will teach ALL that C++ has to offer, it is vast. A reference site, NOT a site for a beginner to learn C/C++, is cppreference. Lots of technical article for C & C++, lots of technical examples.
https://en.cppreference.com/w/
> Accelerated C++ Practical Programming by Example by Andrew Koenig, Barbara E. Moo

This is still a very good book, even if it does not deal with the later versions of the C++ standard.
Lots that one could learn from it.

From 'The Definitive C++ Book Guide and List' stackoverflow
This basically covers the same ground as the C++ Primer, but does so in a quarter of its space. This is largely because it does not attempt to be an introduction to programming, but an introduction to C++ for people who've previously programmed in some other language. It has a steeper learning curve, but, for those who can cope with this, it is a very compact introduction to the language. (Historically, it broke new ground by being the first beginner's book to use a modern approach to teaching the language.) Despite this, the C++ it teaches is purely C++98.
https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list


'What are some best-of-breed C++ programming-by-example guides?' isocpp faq
Here’s a subjective and selective short-list of must-read C++ programming-by-example guides:

Koenig and Moo, Accelerated C++, 336 pgs, Addison-Wesley, 2000, ISBN 0-201-70353-X. Lots of examples using the standard C++ library. Truly a programming-by-example book.

Musser and Saini, STL Tutorial and Reference Guide, Second Edition, Addison-Wesley, 2001, ISBN 0-201-037923-6. Lots of examples showing how to use the STL portion of the standard C++ library, plus lots of nitty gritty detail.
https://isocpp.org/wiki/faq/how-to-learn-cpp#prog-by-example-books
This compiles - but note L28 which may not be as required for the desired result:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>

// compute the median of a vector<double>
double median(std::vector<double> vec) {
	const auto size {vec.size()};

	if (size == 0)
		throw std::domain_error("median of an empty vector");

	std::sort(vec.begin(), vec.end());

	const auto mid {size / 2};

	return size % 2 == 0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid];
}

// compute a student's overall grade from midterm and final exam grades
// and vector of homework grades.
double grade(double midterm, double final, const std::vector<double>& hw) {
	if (hw.size() == 0)
		throw std::domain_error("student has done no homework");

	//return grade(midterm, final, median(hw));
	return (midterm + final + median(hw)) / 3;
}

// read homework grades from an input stream into a vector<double>
std::istream& read_hw(std::istream& in, std::vector<double>& hw) {
	double x;

	while (in >> x)
		hw.push_back(x);

	in.clear();
	return in;
}

int main() {
	std::string name;
	double midterm {}, final {};
	std::vector<double> homework;

	std::cout << "Please enter your first name: ";
	std::cin >> name;
	std::cout << "Hello, " << name << "!\n";

	std::cout << "Please enter your midterm and final exam grades: ";
	std::cin >> midterm >> final;

	std::cout << "Enter all your homework grades, followed by end-of-file: ";

	read_hw(std::cin, homework);

	try {
		const auto final_grade {grade(midterm, final, homework)};

		std::cout << "Your final grade is " << std::setprecision(3) << final_grade << '\n';
	}
	catch (std::domain_error) {
		std::cout << "\nYou must enter your grades. Please try again.\n";
		return 1;
	}
}

My preference for a beginners C++ book is:

Beginning C++20: From Novice to Professional by Ivor Horton
https://amazon.co.uk/Beginning-C-20-Novice-Professional/dp/1484258835/ref=sr_1_10

Beginning C++20: From Novice to Professional
is now one of my main daily reading material, i do like it. thanks Seeplus

And since
Accelerated C++ Practical Programming by Example by Andrew Koenig, Barbara E. Moo is highly recommended by JLBorges
I'll stick to it. I do like the way it's taught, Programming by Example.
Plus it's a fairly concise book, about half the number of pages as the the other books in this thread. so i'll keep on grinding.
thanks for helping me sort out the problems i face with this book.

i'll get hold of Bjarne Stroustrup's "Programming: Principles and Practice Using C++ (2nd Edition)" and add that to my daily reading.

thanks guys

Looking at the revisions to the code made by Seeplus, it got me thinking.

the original code (from the book "Accelerated C++ Practical Programming by Example")
was the author using recursive function when he wrote
return grade(midterm, final, median(hw))
?

1
2
3
4
5
6
7
double grade(double midterm, double final, const std::vector<double>& hw) {
	if (hw.size() == 0)
		throw std::domain_error("student has done no homework");

	//return grade(midterm, final, median(hw));
	return (midterm + final + median(hw)) / 3;
}


i know just very little about recursive functions. Heard it's difficult to understand and not often used (at least from what i'v read) so i haven't really been studying that. just took a quick look at
https://www.learncpp.com/cpp-tutorial/recursion/tutorial/recursion/

and it does seem to be a recursive function. was that related to why the code didn't compile in the first place?
Last edited on
https://www.learncpp.com/cpp-tutorial/recursion/ might help pump some neurons.

The problem with the original code's use of recursion is the supplied parameters in the return statement do not match what is supposed to be passed to the recursively called function.

double grade(double midterm, double final, const std::vector<double>& hw);

A double, another double and a reference to a const std::vector.

The return statement: return grade(midterm, final, median(hw));
M'ok, that third parameter is the what is bollixing things. Passing the return value of a another called function, median in this case.

double median(std::vector<double> vec);

A double is not a reference to a const std::vector. The problem isn't recursion, just a wrong data type being passed.

(Gee, I seem to think I already mentioned data type mismatch earlier....)
M'ok, what are the parameter types in the grade function? double, double and const std::vector.

What is the return type of the median function? double.

In the return statement in the grade function you are recursively calling grade with double, double and double. *BOMB-O!*

C++98 might have allowed that type mismatch, I can't remember. Modern C++ (C++11 or later) certainly doesn't allow it.

The age of the book is my only "complaint." and that is a small issue. It might be very good at teaching C++98.

C++98 is Geoffrey Chaucer territory for C++:
This frere bosteth that he knoweth helle,
And God it woot, that it is litel wonder;
Freres and feendes been but lyte asonder.

(Modern translation):
This friar boasts that he knows hell,
And God knows that it is little wonder;
Friars and fiends are seldom far apart.

At least it isn't ANSI C++, the C++ that predated C++98. Here's an ANSI C++ "Hello World" example:
1
2
3
4
5
6
#include <iostream.h>

void main()
{
   cout << "Hello World!" << endl;
}
^^ void main was never proper, it was just tolerated same as variable length arrays are tolerated.

Moo is a name you should recognize without needing anything more. She worked directly with Bjarne Stroustrup and managed the C++ group for a long time. One of our big names! I also like that she write well, unlike most of the rest of the bigwigs.
Last edited on
The Moo book is part of the old Addison-Wesley C++ In-Depth series edited by Stroustrup - including books by Sutter (C++ standards group convenor) etc. There's about 10 in the set. For C++98 they were excellent. I've got most of them. The problem is that they haven't been updated for newer versions of C++ and don't even cover C++11 - never mind C++20! That's why I can't really recommend them. The other Addison-Wesley C++ books (including those by Myers) are in the same position. Some are from even before C++98! (The last C++ Myers book Effective Modern C++ which covers C++11/14 is published by O'Reilly Media).

For anyone learning to use C++ I'd really advise they use a book that covers at least C++17 and preferable C++20 - together with a compatible compiler.
@seeplus,
shouldn't someone start with C++11 ?
C++17 and C++20 make little sense if someone doesn't know the basics.
the changes are the language now; learning older versions that you have to re-learn to get up to date serves no purpose. Start with the latest version. Its not notably 'more advanced' its just 'the current version'. The 'more advanced' parts the student may not see for a while, but its still c++ 20 without those. Even if something has not changed since C, like a while loop, its still c++ 20 version of that info :)
shouldn't someone start with C++11 ?

Why? With this logic you would probably better off starting by limiting yourself to C++98 (not).

C++17 and C++20 make little sense if someone doesn't know the basics.

All of the C++ standards contain the basics. There are "improvements" in each standard to try to improve the language and make better C++ programs.

IMO there is no reason to limit yourself to the outdated standards, again IMO C++17 should be the minimum, and once all the compilers are totally c++20 compatible move on to C++20.

seeplus wrote:
they [the books] haven't been updated for newer versions of C++ and don't even cover C++11 - never mind C++20!

I've been saying from the start in this thread! Going back to C++98 is not IMO a good starting place for learning C++ now. At a minimum it should be C++11, if not C++17/20.

Pre-C++11 books were great resources when they were originally published. Now they are antiquated and out-dated. There is no getting around that.

This is about LEARNING C++ without prior (or very little) knowledge of the language. Teaching to the C++98 standard hobbles the learner unnecessarily.

A large chunk of C++ is not language standard dependent -- data types, control statements such as loops and if/else statements, etc. C++ shares in common with C -- but using C++98 as the standard for HOW code should be written ignores a lot of what Modern C++ has to offer.

Learn to USE what Modern C++ has to offer first. Then at an intermediate (or expert) level learn how the C++ libraries do the grunt work when dealing with the inner workings of (for example) std::vector or std::string.

Throwing regular arrays and C strings first off at someone who is a "Don't Know Jack" beginner makes intuitively using C++ containers a hard thing to do. Most people will use what they first learned.
If you start with C++11 it doesn't mean you should stop there. I never implied that.
However I don't think all books about C++17 or C++20 will cover older topics like move semantics, smart_ptr, initializer_list... in depth.
I don't think all books about C++17 or C++20 will cover older topics

Well, let's look at a brief description of the C++20 book seeplus mentioned earlier, Beginning C++20: From Novice to Professional 6th ed. Edition

What You Will Learn

Begin programming with the C++20 standard (Just mentioning the use of C++20 doesn't mean it is exclusive C++20 only)

Carry out modular programming in C++ (Not C++20 exclusive)

Work with arrays and loops, pointers and references, strings, and more (Not C++20 exclusive)

Write your own functions, types, and operators (Not C++20 exclusive)

Discover the essentials of object-oriented programming (Not C++20 exclusive)

Use overloading, inheritance, virtual functions, and polymorphism (Not C++20 exclusive)

Write generic function and class templates, and make them safer using concepts (Not C++20 exclusive)

Learn the ins and outs of containers, algorithms, and ranges (Not C++20 exclusive)

Use auto type declarations, exceptions, move semantics, lambda expressions, and much more (Not C++20 exclusive)

Certainly looks like it gives a decent overview of what C++ has to offer that is not C++20 only, while showing the enhancements C++20 gives to the overall C++ toolbox. Concepts and Ranges might be part of C++20, but the book isn't C++20 only.

I have several eBooks that cover C++20 only features. Or C++17 only. This book isn't that restrictive.

This book is certainly on my "look to buy" list. Coming up with the money to purchase on a very limited and fixed income is the major problem why I wait.
This "Modern C++" eBook bundle certainly looks worthy as well:

https://leanpub.com/b/modernccollection
Topic archived. No new replies allowed.