I would like to print a std::unique_ptr which is a class member of Bar.
However, the following code does not work see my comment on stream << bar.foo_unique();
I think I should change my foo_unique() accessor but I don't know how.
#include <iostream>
#include <memory>
class Foo
{
public:
Foo() : n_(1) {}
int n() const { return n_; }
private:
int n_;
};
std::ostream& operator<< (std::ostream& stream, const Foo& foo);
std::ostream& operator<< (std::ostream& stream, const Foo& foo)
{
stream << foo.n();
return stream;
}
class Bar
{
public:
Bar() : m_(2), foo_(), foo_unique_(std::make_unique<Foo>()) {}
int m() const { return m_; }
const Foo& foo() const { return foo_; }
const std::unique_ptr<Foo>& foo_unique() const { return foo_unique_; } // what to return here ?
private:
int m_;
Foo foo_;
std::unique_ptr<Foo> foo_unique_;
};
std::ostream& operator<< (std::ostream& stream, const Bar& bar);
std::ostream& operator<< (std::ostream& stream, const Bar& bar)
{
stream << bar.m() << ",";
stream << bar.foo();
// stream << bar.foo_unique(); // does not work !!!
return stream;
}
int main()
{
Bar bar;
std::cout << bar << std::endl;
}
How can I do that properly ?
edit : I want stream << bar.foo_unique(); to have the same behaviour as stream << bar.foo();
There is no output operator defined for std::unique_ptr<T>: it is a bit sad but many of the C++ classes are lacking output operators. The easiest approach is to just print the pointer:
stream << bar.foo_unique().get();
if you want to get the actually pointer printed or you'd dereference the pointer
stream << *bar.foo_unique();
if you want to get the pointee printed.
To use the output operator you can create your own output operator taking a std::unique_ptr<Foo> assuming Foo is a user-defined type. You'd put it into the same namespace as where Foo is defined:
std::ostream& operator<< (std::ostream& out, std::unique_ptr<Foo> const& foo) {
return out << *foo; // or foo.get()depending on what you want to get printed
}
There is no implicit conversion from std::unique_ptr<T> to T const& which is preventing the stream insertion operator from being determined. You have a couple of options here though. The first option is to provide one override of operator<< for std::unique_ptr<T> and one for T&. This can get tedious if you have use both std::unique_ptr and non-owning raw pointers or references. The second option is to provide a single templated version of operator<< to handle instances of std::unique_ptr<T> and then individual ones to handle T const&. Below is an example of how to accomplish this.
std::ostream& operator<< (std::ostream& out, Foo const& arg)
{
// output stuff here
return out;
}
template<class T>
std::ostream& operator<< (std::ostream& out, std::unique_ptr<T> const& arg)
{
return out << *arg;
}
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;
}
};
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;
}
};
Hello dear StackOverflowers!
I am having trouble with a template structure which comprises another (but non-template) structure.
Here's the thing:
Structure B is non-template and is defined inside a template structure A.
Strcure B is "protected" because it exists only for the purposes of structure A and no-one and nothing else shall use it outside of structure A.
There's an overload of operator<< for structure B, so that objects of type B can be sent to the standard output "cout << B_type_object;" (and it's A's friend so that it can access B which is protected).
The aforementioned printing of B objects is done only by methods defined in A (because of "2.").
As long as both structures are non-template everything works like a charm.
The moment A is a template I get an error message (provided in the code section).
Here is the working code (where A is not template):
#include <iostream>
#include <string>
struct A
{
protected:
struct B
{
std::string something;
B& operator= (const std::string&& rhs)
{
this->something = std::move(rhs);
return *this;
}
};
B B_object;
friend std::ostream& operator<< (std::ostream& output, const typename A::B& ob);
public:
void method ()
{
B_object = "This is text.";
//No error here
std::cout << B_object;
}
};
std::ostream& operator<< (std::ostream& output, const typename A::B& ob)
{
output << ob.something;
return output;
}
int main(int argc, const char * argv[])
{
A obj;
obj.method();
return 0;
}
This is the code which doesn't work
#include <iostream>
#include <string>
template <typename T>
struct A
{
T variable;
protected:
struct B
{
std::string something;
B& operator= (const std::string&& rhs)
{
this->something = std::move(rhs);
return *this;
}
};
B B_object;
template <typename X> friend std::ostream& operator<< (std::ostream& output, typename A/*<X>*/::B& ob);
public:
void method ()
{
B_object = "This is text.";
//ERROR: Invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'A<int>::B')
std::cout << B_object;
}
};
template <typename X>
std::ostream& operator<< (std::ostream& output, typename A<X>::B& ob)
{
output << ob.something;
return output;
}
int main(int argc, const char * argv[])
{
A<int> obj;
obj.method();
return 0;
}
Just declare the operator inline in B, then it works:
...
struct B
{
std::string something;
B& operator= (const std::string&& rhs)
{
this->something = std::move(rhs);
return *this;
}
friend std::ostream& operator<< (std::ostream& output, const typename A<T>::B& ob)
{
output << ob.something;
return output;
}
};
...
This has also the advantage that your are not friending any operator<< of any A<X>. In your example, the operator taking A<string>::B would also be a friend of A<int>::B. For a more in-depth explanation, see this answer:
https://stackoverflow.com/a/4661372/36565