The files are organized as following:
//MyClass.h
#pragma once
namespace std {
class ostream;
};
class MyClass
{
private:
int a;
public:
friend std::ostream& operator<<(std::ostream& o, const MyClass& obj);
};
//MyClass.cpp
#include<iostream>
std::ostream& operator<<(std::ostream& o, const MyClass& obj)
{
o << obj.a << std::endl;
return o;
}
//main.cpp
#include"MyClass.h"
#include<iostream>
int main()
{
MyClass obj;
std::cout << obj;
}
It failed compiling with errors on overloading operator<<:
Error C2371 'std::ostream': redefinition; different basic types
What's the issue here and how to correct it?
As other people noted,
ostreamis not a class but an alias to a template instantiation, basicallyostream = basic_ostream<char>. This is an implementation detail of the standard library; it's there because it needs to support alsowostream(which isbasic_ostream<wchar_t>) and possibly other stream types. But other implementations may do it differently (using e.g. source code generation) or very differently (distributing pre-compiled modules). You should not depend on any particular implementation.You should not declare anything inside the
stdnamespace (except stuff which the C++ Standard explicitly permits). To forward-declareostreamand such, use#include <iosfwd>in your header file.Alternatively, just do
#include <iostream>instead of forward declaration — less technical details to remember vs slightly slower compilation — do your own judgment on what is better.