You are here:

C++/parse error before '<'

Advertisement


Question
Hi 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  

Answer
Cor! 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.

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.