Like in this code :
#include <iostream>
enum class A {
a,
b
};
std::ostream& operator<<(std::ostream& os, A val)
{
return os << val;
}
int main() {
auto a = A::a;
std::cout << a;
return 0;
}
When I did not provide std::ostream& operator<<(std::ostream& os, A val) the program didn't compile because A::a didn't have any function to go with <<. But now when I've already provided it, it produces garbage in my terminal and on ideone, it produces a runtime error (time limit exceeded).
std::ostream& operator<<(std::ostream& os, A val) {
return os << val;
}
This causes infinite recursion. Remember that os << val is really seen to the compiler operator<<(os,val) in this instance. What you want to do is print the underlying value of the enum. Fortunately, there is a type_trait that allows you to expose the underlying type of the enum and then you can cast the parameter to that type and print it.
#include <iostream>
#include <type_traits>
enum class A {
a, b
};
std::ostream& operator<<(std::ostream& os, A val) {
return os << static_cast<std::underlying_type<A>::type>(val);
}
int main() {
auto a = A::a;
std::cout << a;
}
std::ostream& operator<<(std::ostream& os, A val)
{
return os << val; // Calls the function again.
// Results in infinite recursion.
}
Try
std::ostream& operator<<(std::ostream& os, A val)
{
return os << static_cast<int>(val);
}
Related
myclass is a C++ class written by me and when I write:
myclass x;
cout << x;
How do I output 10 or 20.2, like an integer or a float value?
Typically by overloading operator<< for your class:
struct myclass {
int i;
};
std::ostream &operator<<(std::ostream &os, myclass const &m) {
return os << m.i;
}
int main() {
myclass x(10);
std::cout << x;
return 0;
}
You need to overload the << operator,
std::ostream& operator<<(std::ostream& os, const myclass& obj)
{
os << obj.somevalue;
return os;
}
Then when you do cout << x (where x is of type myclass in your case), it would output whatever you've told it to in the method. In the case of the example above it would be the x.somevalue member.
If the type of the member can't be added directly to an ostream, then you would need to overload the << operator for that type also, using the same method as above.
it's very easy, just implement :
std::ostream & operator<<(std::ostream & os, const myclass & foo)
{
os << foo.var;
return os;
}
You need to return a reference to os in order to chain the outpout (cout << foo << 42 << endl)
Even though other answer provide correct code, it is also recommended to use a hidden friend function to implement the operator<<. Hidden friend functions has a more limited scope, therefore results in a faster compilation. Since there is less overloads cluttering the namespace scope, the compiler has less lookup to do.
struct myclass {
int i;
friend auto operator<<(std::ostream& os, myclass const& m) -> std::ostream& {
return os << m.i;
}
};
int main() {
auto const x = myclass{10};
std::cout << x;
return 0;
}
Alternative:
struct myclass {
int i;
inline operator int() const
{
return i;
}
};
myclass is a C++ class written by me and when I write:
myclass x;
cout << x;
How do I output 10 or 20.2, like an integer or a float value?
Typically by overloading operator<< for your class:
struct myclass {
int i;
};
std::ostream &operator<<(std::ostream &os, myclass const &m) {
return os << m.i;
}
int main() {
myclass x(10);
std::cout << x;
return 0;
}
You need to overload the << operator,
std::ostream& operator<<(std::ostream& os, const myclass& obj)
{
os << obj.somevalue;
return os;
}
Then when you do cout << x (where x is of type myclass in your case), it would output whatever you've told it to in the method. In the case of the example above it would be the x.somevalue member.
If the type of the member can't be added directly to an ostream, then you would need to overload the << operator for that type also, using the same method as above.
it's very easy, just implement :
std::ostream & operator<<(std::ostream & os, const myclass & foo)
{
os << foo.var;
return os;
}
You need to return a reference to os in order to chain the outpout (cout << foo << 42 << endl)
Even though other answer provide correct code, it is also recommended to use a hidden friend function to implement the operator<<. Hidden friend functions has a more limited scope, therefore results in a faster compilation. Since there is less overloads cluttering the namespace scope, the compiler has less lookup to do.
struct myclass {
int i;
friend auto operator<<(std::ostream& os, myclass const& m) -> std::ostream& {
return os << m.i;
}
};
int main() {
auto const x = myclass{10};
std::cout << x;
return 0;
}
Alternative:
struct myclass {
int i;
inline operator int() const
{
return i;
}
};
I find following boost code
for (auto entry : boost::make_iterator_range(boost::filesystem::directory_iterator(dir_path), {})) {
std::cout << entry << std::endl;
}
entry can be output with dir path, I guess c++ has feature like java Class#toString to custom output string, I try following code:
class C {
str to_string() {
return "prpr";
}
};
TEST_F(FileTest, Draft1) {
C c;
std::cout << c << std::endl;
}
I expect output "prpr", but it doesn't work, how to fix it?
C++ doesn't call any "to_string" or similar function automatically. Instead you must overload the operator<< function for your class:
class C
{
public:
friend std::ostream& operator<<(std::ostream& os, C const& c)
{
return os << "prpr";
}
};
If you want to pass a class to std::cout you need to overload the << operator for std::ostream in your class.
class C {
friend std::ostream& operator<<(std::ostream& os, const C& c);
};
std::ostream& operator<<(std::ostream& os, const C& c){
os<<"prpr";
return os;
}
myclass is a C++ class written by me and when I write:
myclass x;
cout << x;
How do I output 10 or 20.2, like an integer or a float value?
Typically by overloading operator<< for your class:
struct myclass {
int i;
};
std::ostream &operator<<(std::ostream &os, myclass const &m) {
return os << m.i;
}
int main() {
myclass x(10);
std::cout << x;
return 0;
}
You need to overload the << operator,
std::ostream& operator<<(std::ostream& os, const myclass& obj)
{
os << obj.somevalue;
return os;
}
Then when you do cout << x (where x is of type myclass in your case), it would output whatever you've told it to in the method. In the case of the example above it would be the x.somevalue member.
If the type of the member can't be added directly to an ostream, then you would need to overload the << operator for that type also, using the same method as above.
it's very easy, just implement :
std::ostream & operator<<(std::ostream & os, const myclass & foo)
{
os << foo.var;
return os;
}
You need to return a reference to os in order to chain the outpout (cout << foo << 42 << endl)
Even though other answer provide correct code, it is also recommended to use a hidden friend function to implement the operator<<. Hidden friend functions has a more limited scope, therefore results in a faster compilation. Since there is less overloads cluttering the namespace scope, the compiler has less lookup to do.
struct myclass {
int i;
friend auto operator<<(std::ostream& os, myclass const& m) -> std::ostream& {
return os << m.i;
}
};
int main() {
auto const x = myclass{10};
std::cout << x;
return 0;
}
Alternative:
struct myclass {
int i;
inline operator int() const
{
return i;
}
};
I am trying to use std::accumulate to write into std::ostream in the operator<< (this is just a minimum example, I know this could be implemented much simpler):
#include <iterator>
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
struct A {
A() : v(std::vector<int>()){};
std::vector<int> v;
A(std::vector<int> v) : v(v){};
friend std::ostream& operator<<(std::ostream& stream, A& a);
};
std::ostream& operator<<(std::ostream& stream, A& a) {
// I need something similar to
// return std::accumulate(a.v.begin(), a.v.end(), "",
std::ostream_iterator<int>(stream, " "));
// or:
// return std::accumulate(a.v.begin(), a.v.end(), stream,
[]()->{});
}
int main(int argc, char* argv[]) {
std::vector<int> v({1, 2, 3, 4, 5});
A a(v);
std::cout << a << std::endl;
return 0;
}
How can I make this operator work?
Don't use accumulate, use copy:
std::ostream& operator<<(std::ostream& stream, A& a) {
std::copy(a.v.begin(), a.v.end(), std::ostream_iterator<int>(stream, " "));
}
This is actually one of the examples at the above reference page (though for std::copy, not for std::ostream_iterator.
You may abuse of std::accumulate like this:
std::ostream& operator<<(std::ostream& stream, A& a) {
return std::accumulate(a.v.begin(), a.v.end(), std::ref(stream),
[](std::ostream& stream, int e)
{ return std::ref(stream << " " << e); });
}
Demo
It can be done:
// Using accumulate
std::ostream& out_acc(const std::vector<int>& is, std::ostream& out)
{
return std::accumulate(is.begin(),
is.end(),
std::ref(out),
[](std::ostream& os, int i) -> std::ostream&
{ return os << i << ", "; });
}
// Using for_each
std::ostream& out_for(const std::vector<int>& is, std::ostream& out)
{
std::for_each(is.begin(),
is.end(),
[&](int i)
{ out << i << ", "; });
return out;
}
for_each is the natural choice, as you don't really care much about the accumulated value.
Since you mentioned that for_each could be used, too (and accumulate was just mentioned to confuse the Martians):
std::ostream& operator<<(std::ostream& stream, const A& a) {
std::for_each(begin(a.v), end(a.v), [](int i){ std::cout << i << " "; });
return stream;
}
Beware: You'll have a trailing space here. You'll need to handle the first or last element differently, if you want to avoid that (for instance by using a counter in the lambda).