0

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?

Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
M.Ionut
  • 187
  • 1
  • 3
  • 15

2 Answers2

2

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.

Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
1

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 ints 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.

cigien
  • 57,834
  • 11
  • 73
  • 112
  • Thank you a lot! What if we weren't dealing with fundamental types? – M.Ionut Apr 05 '20 at 16:14
  • 1
    @M.Ioan Added an explanation – cigien Apr 05 '20 at 16:19
  • 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