tags:

views:

708

answers:

3

Hi,

the following piece of C++ code compiled two years ago in a suse 10.1 Linux machine.

#ifndef DATA_H
#define DATA_H
#include <iostream>
#include <iomanip>


inline double sqr(double x) { return x*x; }
enum   Direction { X,Y,Z };

inline Direction next(const Direction d)
{
  switch(d)
  {
  case X: return Y;
  case Y: return Z;
  case Z: return X;
  }
}

inline ostream& operator<<(ostream& os,const Direction d)
{
  switch(d)
  {
  case X: return os << "X";
  case Y: return os << "Y";
  case Z: return os << "Z";
  }
}
...
...

Now, I am trying to compile it on Ubuntu 9.10 and I get the error:

data.h:20: error: expected initializer before ‘&’ token

which is referred to the line of:

inline ostream& operator<<(ostream& os,const Direction d)

the g++ used on this machine is:

Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.1-4ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9) 

Could you give me some hint about this error?

Thanks

P.D. If i do std::ostream, I get the errors:

data.h:20: error: declaration of ‘operator<<’ as non-function
data.h:20: error: ‘ostream’ was not declared in this scope
data.h:20: error: ‘os’ was not declared in this scope
data.h:20: error: expected primary-expression before ‘const’
+4  A: 

The ostream class is part of the C++ standard iostream library, and is defined in the namespace std

so you probably should add std:: before ostream
or

using namespace std;

but, as stated in one of the comments :

You should never use using namespace std in a header as it can propagate to other files.

f4
-1. You should **never** use `using namespace std` in a header as it can propagate to other files.
Yacoby
That's not a reason for not mentioning it in the answer, he could have the same problem in a cpp file (and there is good chances for it). Yet I agree I should have added a disclaimer :) I never do it myself so I didn't think about it -- fix done you can call back your down votes if you forgive me :)
f4
@f4: Forgiven and removed. `:)`
sbi
@f4 Also removed the downvote :)
Yacoby
+6  A: 

As everything in the C++ standard library, ostream lives in the std namespace, so it's std::ostream.

I believe that, if this used to compile, this was in error.

sbi
hi, i dothat, and then i get data.h:23: error: declaration of ‘operator<<’ as non-functiondata.h:23: error: ‘ostream’ was not declared in this scopedata.h:23: error: ‘os’ was not declared in this scopedata.h:23: error: expected primary-expression before ‘const’
Werner
by the way, can the code be formatted in the comments?
Werner
@Werner: Not really. You should edit your question with new information. That said, use the backticks: \`code goes here\` to get *some* formatting: `code goes here`. I escaped the former backticks with a backslash.
GMan
If i do std::ostream, I get the errors:`\data.h:20: error: declaration of ‘operator<<’ as non-functiondata.h:20: error: ‘ostream’ was not declared in this scopedata.h:20: error: ‘os’ was not declared in this scopedata.h:20: error: expected primary-expression before ‘const’`\
Werner
@Werner: Technically it's not guaranteed that `<iostream>` includes `<ostream>` (although I have a hard time imagining how an implementation could define `std::cout` without doing so). So you should include `<ostream>`. Anyway, your `operator<<` for any type `T` should then look like this: `std::ostream
sbi
@Werner just add std:: to each occurrence of ostream, not only to the first.
Tadeusz Kopec
+1  A: 

You forgot to put std:: in front of each occurrence of ostream. Also, you should take Direction as a reference (while in this case, it won't hurt):

inline std::ostream& operator<<(std::ostream& os,const Direction& d)
Alexandre Hamez
What is the gain in handling a reference to an enum? Whether passed as a reference or `int`, it'd be the same mount of data: 32 or 64-bits.
spoulson
Passing built-ins or enums as a const reference is not such a good practice. Passing them by value, as in OP code, is perfectly good.
Gorpik
That's why I said: `(while in this case, it won't hurt) :-)`
Alexandre Hamez
It is not that it won't hurt: it just does not apply to this case.
Gorpik
Honestly, do you really think it will change anything? And as says sbi in one of his comment: ` Anyway, your operator<< for any type T should then look like this: std::ostream` This is the good practice when overloading operator<<.
Alexandre Hamez