0

My question is different because it is pertaining to a newer version of C++.

This question was asked already here and I'm referring to this answer. However this was asked and answered back in 2009 and it is quite dated to the current compilers and versions of the C++ language. However; here it is again.

I have a simple template class that I would like to overload the stream operator, but in my case here: I'm using Visual Studio 2017 CE v4.6.01055 with compiler c++ language feature set to ISO C++ Latest Draft Standard (/std:c++latest) simply put C++17. I'm build it in x86 debug mode.

I have tried the solution from the Q/A above but it keeps giving me compiler errors.

Here is the simple class

template<class T>
class Point {
public:
    T mX;
    T mY;

    Point() : mX(0), mY(0) {}
    Point( T x, T y ) : mX( x ), mY( y ) {}
    Point( T& x, T& y ) : mX( x ), mY( y ) {}
    Point( T* x, T* y ) : mX( *x ), mY( *y ) {}

    friend operator<<( std::ostream& out, const Point<T>& p );
}

The suggestion stated that you should make a single instance called specialization of that template a friend. The user also stated that you needed to put the declaration of operator<< above the class template declaration. I've tried that; I've tried moving the method out the header into the cpp, below, above it; I tried to even put the definition within the class as well, and no matter what I try; I can not get it to compile correctly.

I even found this answer and I tried the pattern there but it is still failing in c++17. At least at this point it is compiling without the <> specialization and failing to build, but when I add that in it fails to compile.

What is the proper syntax and or placement to overload the stream operator as a friend to a simple class template in c++17? I don't necessarily mean the syntax of the actual operator<<() itself... it had to deal more with the actual placement of the declarations and definitions. The only piece of syntax that I wasn't sure of but found out from the previous answers that I've shown here was the part about making it a specialization; that part was new to me.

EDIT

I don't know what was causing the compiler or linker errors. The declarations and definitions were the same. I ended up changing the 2nd param from const Point<T>& to Point<T> in the declarations and definition and it compiled and built. I then went ahead and changed them back to const Point<T>& and it now compiles, builds and gives me the output without error.

It could of been a bug within Visual Studio since I did just update it to the newest version last night. I don't know what was causing it; but what ever it was is now resolved.

Francis Cugler
  • 7,788
  • 2
  • 28
  • 59
  • 1
    "*However this was asked and answered back in 2009 and it is quite dated to the current compilers and versions of the C++ language.*" Why do you think it is dated? Just because a question is old doesn't mean the answers don't still apply. They're all still legal C++. – Nicol Bolas Mar 10 '18 at 05:01
  • @NicolBolas and over the years compilers do change; syntax does change, things become deprecated, newer features are added. New OS come out. – Francis Cugler Mar 10 '18 at 05:03
  • Has to be `friend std::ostream& operator<<(std::ostream& out, const Point& p)` – Justin Mar 10 '18 at 05:03
  • I'm not sure usually if I'm doing basic classes that aren't template I pass the values by const reference to the friend operator; I prefer to pass as const ref. – Francis Cugler Mar 10 '18 at 05:04
  • It compiles in C++14 right? – gsquaredxc Mar 10 '18 at 05:08
  • I didn't try, but I'm using c++17 – Francis Cugler Mar 10 '18 at 05:08
  • Maybe it was a bug in visual studio... I changed the 2nd param to be `Point` as opposed to `const Point&` and it did compile and built without errors. Then I changed it back to `const Point&` and I think it is working now. I did just update to the newest version of Visual Studio last night. – Francis Cugler Mar 10 '18 at 05:10

1 Answers1

1

The syntax for a friend function is almost the same as with any other function. In your case, you would do:

friend std::ostream& operator<< (std::ostream& out, const Point<T>& p )
{
    //do whatever
    return out;
}

This makes an operator that takes in a Point<T> and prints it however you want to. For more info, look here.
EDIT:
In terms of usage and placement, you can only use the function when the class is defined, so it is general practice to declare it in the same files as your class. The only real difference between a class friend function and a template friend function is that the compiler has to interpret the friend function for each data type the friend object is. This is part of why having it defined in the same files as the template is the norm. Because of this, it is, for all intents and purposes, also a template function,hence the specialization. If you declare it outside the body of the template, you need to treat it as such.

Hawkeye5450
  • 672
  • 6
  • 18
  • I know the syntax of the actual function; that isn't the issue; it is regards to when using them as friend with a class template; the placement of the declarations, definitions etc. – Francis Cugler Mar 10 '18 at 05:18
  • That explanation makes it easier to understand the overall design or order that they have to be in. – Francis Cugler Mar 10 '18 at 06:04