What is the difference between these two and why does one compile fine compared to the other :S

//MyFile.h
#include<iostream>
using namespace std;

inline std::ostream& operator << (std::ostream& Str, const RGB &Rgb)
{
    Str<<"R: "<<(int)Rgb.R<<"  G: "<<(int)Rgb.G<<"  B: "<<(int)Rgb.B;
    return Str;
}


//Main.cpp

#include <iostream>
#include "MyFile.h"

using namespace std;

int main()
{
   cout<<Rgb(16777215);      //Results in an error!
}

The above gives an error but the below thing does not:

//Main.cpp

#include <iostream>

using namespace std;

inline std::ostream& operator << (std::ostream& Str, const RGB &Rgb)
{
    Str<<"R: "<<(int)Rgb.R<<"  G: "<<(int)Rgb.G<<"  B: "<<(int)Rgb.B;
    return Str;
}

int main()
{
   cout<<Rgb(16777215);      //Results are printed correctly.
}

Dani AI

Generated

For : the difference isn’t “header vs .cpp” magic — it’s what the compiler has seen when it compiles the operator<< definition. If the operator’s body accesses RGB members, the full RGB type must be visible before that body is compiled. Defining the operator in a .cpp after RGB is known will compile; putting the operator in a header that’s included before RGB is defined will produce errors about an unknown or incomplete type.

As noted, operator<< is a binary operator (stream on the left, value on the right), so calling it with stream syntax supplies both operands. A common mistake is declaring a variable and then writing something that looks like a function call on that variable (which produces a “called object is not a function” error) instead of constructing or initializing an RGB object and streaming that object.

Practical fixes and best practices: ensure the struct/class RGB is declared before any non-inline operator<< body that accesses its members; or put only the operator<< prototype in the header and place the implementation in one .cpp file where RGB is defined; if the operator is implemented in a header included by multiple translation units, mark it inline (or define it as an inline friend inside the class) to satisfy the One‑Definition Rule (ODR). Never use using namespace std in headers; prefer std:: qualifiers and include guards or #pragma once. If the operator needs private access, either make it a friend or provide public accessors.

Typical compile messages that point to these problems are “unknown type name ‘RGB’”, “incomplete type”, or “called object is not a function” — those indicate include/definition order or a misuse of a variable as if it were a constructor call.

Neither of the code snippets you posted compile. This is your second example with a couple changes so that I could make it compile, but it also has a problem.

The operator << has two parameters, but main() is passing only one parameter. Fix that and both examples will compile.

#include <iostream>

using namespace std;
struct RGB
{
    int R, G, B;
};

inline std::ostream& operator << (std::ostream& Str, const RGB &Rgb)
{
    Str<<"R: "<<(int)Rgb.R<<"  G: "<<(int)Rgb.G<<"  B: "<<(int)Rgb.B;
    return Str;
}

int main()
{
    RGB Rgb;
   cout<<Rgb(16777215);      
commented: Thank you +5
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.