I am wondering if I could write, for instance: <<(object, cout);
or <<(cout,object);
where object is a user defined class which has the <<
operator overloaded, just as one could write:
int a = +(2,3);
and obtain the expected result, as in int a = 2 + 3;
.
Furthermore, what should one do if this is possible, but requires a few steps? Should one overload the <<
operator with two different signatures?

- 3,777
- 9
- 27
- 53

- 187
- 1
- 3
- 15
-
That's just function notation, you can't name a function `<<`. – Aluan Haddad Apr 05 '20 at 16:07
2 Answers
just as one could write: int a = +(2,3); and obtain the expected result, as in int a = 2 + 3;
No, you have a misunderstanding. +(2, 3)
will go by the associativity of the comma operator and assign +3
(3) to the variable a
.
Therefore, int a = +(2, 3)
is the same as int a = 3
, and not int a = 2 + 3
I am wondering if I could write, for instance: <<(object, cout); or <<(cout,object);
No, you can't.
If you want to use the operators in that fashion then you should call its fully qualified name, for example:
operator+
instead of +
operator<<
instead of <<
Note:
This will not work for fundamental datatypes. Take care of the class scope and namespaces when you are using the overloaded versions of these operators.

- 3,777
- 9
- 27
- 53
-
Ok, thank you! Could you expand more on what is happening when writing `a = +(2, 3);` ? – M.Ionut Apr 05 '20 at 16:00
-
You can do this, e.g.
operator<<(std::cout, "hi");
This expression
int a = +(2, 3);
is not doing operator+
. It's first applying the ,
sequence operator, which gives 3
, and then applying unary +
, which gives 3.
You can't do this
int a = operator+(2, 3); // error
because int
s are fundamental types.
If you have user defined types S
, then the following snippets have the same meaning
S s{};
std::cout << s;
auto x = s + s;
is the same as
S s{};
operator<<(std::cout, s);
auto x = operator+(s, s);
assuming the operators are defined for S
, the correct operator will be called.

- 57,834
- 11
- 73
- 112
-
-
1
-
Thanks a lot, I didn't know that. This `operator<<(cout, "hi")` does compile and print "hi" though. – cigien Apr 05 '20 at 16:24
-
@cigien -- yup, I just tried it. Not sure why. But `operator<<(std::cout, 3)` doesn't work. – Pete Becker Apr 05 '20 at 16:26
-
@PeteBecker yeah, and neither does `operator<<(std::cout, int{3})` either, so it's a different explanation. Seems ambiguous for some reason. – cigien Apr 05 '20 at 16:27
-
@PeteBecker `3` is of a fundamental datatype whereas `std::string` is not – Ardent Coder Apr 05 '20 at 16:27
-
I've deleted my previous comment; it came from a misreading of the documentation. Nevertheless: there are a handful of types for which the stream inserter is a member of `std::ostream`, and for those types, `operator<<(std::cout, value)` won't work, but `std::cout.operator<<(value)` will. The most interesting types where this applies are the numeric types. – Pete Becker Apr 05 '20 at 16:32
-
@PeteBecker ok, so that's where the ambiguity comes from for `int`. I'm keeping the answer unchanged then. – cigien Apr 05 '20 at 16:33
-
@ArdentCoder -- it's not a matter of fundamental types. It's the somewhat arbitrary requirement that stream inserters for **numeric** types (and a few others) are defined inside `basic_ostream`. You have to look at the list; it's not a trivial classification. – Pete Becker Apr 05 '20 at 16:34
-
@PeteBecker I know, but I was taught that simple memorization trick instead of learning the whole list :P – Ardent Coder Apr 05 '20 at 16:34
-
@PeteBecker I recommend you learn that trick lol. For serious purposes, refer the documentation. – Ardent Coder Apr 05 '20 at 16:48