C++/parse error before '<'
Expert: Ralph McArdell - 3/20/2005
QuestionHi Ralph
I meant to implement a function that should use the for_each feature, so I was looking at some examples of how to use for_each. My lecturer gave me an example (provided below) but surprisingly didn't compile. My question is that what could the problem be? Is there any package I need to include?
The error I get:
"parse error before '<'"
And pointing at the line
template<class T> struct print_it : public unary_function<T, void> {
Why doesn't it recognise the syntax?
#include <iostream>
#include <algorithm>
using namespace std;
/*
template<typename InputIter, typename UnaryFunction>
UnaryFunction for_each(InputIter first, InputIter last, UnaryFunction f) {
while (first != last)
f(*first++);
return f;
}
*/
template<class T> struct print_it : public unary_function<T, void> {
ostream &os;
int count;
print_it(ostream& out) : os(out), count(0) {}
void operator() (T x) { os << x << ' '; ++count; }
};
int main() {
int A[] = {1, 4, 2, 8, 5, 7};
const int N = sizeof(A) / sizeof(int);
print_it<int> P = for_each(A, A + N, print_it<int>(cout));
cout << endl << P.count << " objects printed." << endl;
}
Thanks in advance
Steve
AnswerCor! At last a _real_ C++ question!
Sorry, but this weekend I have add all sorts of off topic only vaguely to do with C++ questions and people wanting me to do their homework without even trying themselves!
As you suspect you have not included all the correct header 'files' (the term 'package' is not really used in C++).
The correct header to include is functional. I just added this to your code:
#include <iostream>
#include <algorithm>
#include <functional> // For std::unary_function
I found out which header to include by looking in my reference book for the C++ standard library - The C++ Standard Library A Tutorial and Reference by Nicolai M. Josuttis. I suggest you try and get hold of a copy if you are doing much with the C++ standard library, I find it indispensable.
By the way I placed the word files in quotes when referring to header files above as the C++ standard headers, although usually supplied as files, may in some clever high tech compiler implementation be recognised just by their names - one reason they have no extension - and the compiler adds in the declarations and definitions and whatever that the standard states is in the header automatically. At least that is how I understood the reasoning by the standardisation people...
Now when the C++ library headers are files they will often include others. Exactly which ones depend on the particular implementation of the C++ standard library you are using - so the code may have compiled for your lecturer as maybe in their implementation algorithm or iostream need something from functional and so included it.
In fact you do not need to go to these lengths - it is quite alright to ignore std::unary_function altogether. In fact the function does not even need to be a functor class - it can be a plain ordinary function. I use std::for_each a lot and I have not used std::unary_function recently at all:
void do_stuff_for_one_element( ElementType const & elem )
{
// does stuff with elem
}
typedef std::vector< ElementType > ElementVectorType;
// ...
ElementVectorType elements;
// ...
std::for_each( elements.begin(), elements.end(), do_stuff );
// ...
Which calls do_stuff for each element of elements - a std::vector of some type ElementType.
Note: all code fragments have _not_ been compiled and are for example use only ... sorry for any typos or other inaccuracies!
The only time I need to resort to writing a functor class is where each call needs to access some additional data common to each call, and is the same for each call. This I pass into the functor's constructor and store as member data for the duration of the object - quite often as a reference (preferably const references). The you end up with something like so:
class DoStuff
{
public:
DoStuff( SomeType const & otherData )
: mOtherdata( otherData )
{
}
void operator()(ElementType const & elem )
{
// do stuff with elem, using mOtherData as required
}
private:
SomeType const & mOtherData
};
and then the usage in for_each might look like:
// ...
std::for_each( elements.begin(), elements.end(), DoStuff(someData) );
// ...
where someData is of type SomeType.
Also I note that you are using a very unreadable compact layout. The placement of the opening brace on the same line as the statement referring to it is outdated and people generally agree it is not very readable (although that is where any agreement on readability ends!). Common layouts place the opening and closing braces in line with each other viz:
void Some_Function()
{
// code
}
or maybe:
void Some_Function()
{
// code
}
or even:
void Some_Function()
{
// code
}
Note that I have used a ridiculously large indentation of 8 spaces. This is because I notice that posting via AllExperts may trim leading white space or use a proportional font with a thin space character. Usual indentations are between 2 and 4 or 5 spaces - otherwise you tend to end up way over on the right hand side of the line before you have done much - and many places prefer lines to be around 80 characters long or less - so you do not need high resolution displays to open a wide enough editor window to read a whole line.
So why layout your code nicely you ask? The compiler does not care. This is of course true but code needs to be read by people as well - for example your code is read by your lecturer (who you mention wrote it or at least provided it to you), their students such as yourself, and now me!
In real applications most of the time (80% is an oft quoted figure) is spent maintaining an application in its life time - so that code needs to be read and updated much more often that it is originally written - often by people who had no hand in writing it.
So the clearer the code the easier it is for us poor humans to see what is going on.
Anyhow, rant over! Hope this fixes your problem and you can get on and complete your task. Have fun.