0

I have a number of operator<<() functions that start by doing something similar, so I want to abstract that. Here's a minimal reproducible case of what I'm trying to do (with all the complexity ripped out). Note that it doesn't compile. If it did compile, I would expect the program to print the number 3 on a line by itself.

/* clang++ -std=c++14 -Wall -Wextra foo.cc -o foo */ #include <ostream> #include <iostream> using std::cout; using std::endl; using std::ostream; ostream& BaseFunction(ostream& os, const int x) { return os << x; } int main(int argc, char *argv[]) { cout << BaseFunction(cout, 3) << endl; } 

The error starts like this:

foo.cc:17:8: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'ostream') cout << BaseFunction(cout, 3) << endl; ~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~ 

and then offers a whole lot of "no known conversion from ostream to T" suggestions.

Anyone see what I've done wrong?

3
  • Take out the cout in BaseFunction(cout, 3) << endl; and it should work. Commented Aug 7, 2020 at 16:44
  • 3
    I'm not sure what your goal was, but maybe you wanted this pattern? Commented Aug 7, 2020 at 16:48
  • Clever work-around @MooingDuck, thanks! Commented Aug 13, 2020 at 8:06

4 Answers 4

5

Basefunction(cout, 3) returns cout.

Therefore, the last line is equivalent to

cout << 3; cout << cout << endl; 

Since cout << cout makes no sense, you get an error.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that's exactly right. I was copying what I'd done with operator<<() and missed the important detail of how overrides make it all work. I accepted the response from @blindy simply because on first reading that was the one that clicked for me.
3

You're using an incredibly weird and unique (ie bad) pattern for this, and the way to use it would be:

BaseFunction(cout, 3) << endl; 

Note that you pass your input stream to your function as a parameter, and since you return the stream as an output, and there is no overload of operator<< that takes a stream on the left and right sides at the same time, the regular way of using C++ streams doesn't work here.

The usual way this is done is adding an operator<< overload that takes a left-side stream and a right-side custom object and that does whatever you need it to do to display your object. In your case, replace the function with one that doesn't take the stream as an argument and returns a custom object that you can then use to overload the streaming operator.

1 Comment

Thanks. The pattern was weird because I was copying the operator<<() pattern and missed the important detail of how the override makes it all work. Thanks for explaining it in such good detail.
2

What you are doing is essentially defining a custom stream manipulator. That can be implemented more like this instead:

/* clang++ -std=c++14 -Wall -Wextra foo.cc -o foo */ #include <iostream> using std::cout; using std::endl; using std::ostream; struct myValue { int value; }; myValue BaseFunction(const int x) { return myValue{x}; } ostream& operator<<(ostream &os, const myValue &v) { return os << v.value; } int main(int argc, char *argv[]) { cout << BaseFunction(3) << endl; } 

Live Demo

Comments

1

You can try this:

BaseFunction(cout, 3); cout << endl; 

I think the ostream can't output an ostream.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.