我想打印一个std :: unique_ptr,它是Bar的一个类成员。 但是,以下代码无效,请参阅我对 stream<<的评论bar.foo_unique(); 我想我应该改变我的foo_unique()访问器,但我不知道如何。
#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;
}
我该如何正确地做到这一点?
编辑:我想要流&lt;&lt; bar.foo_unique();具有与流&lt;&lt;相同的行为bar.foo();
答案 0 :(得分:8)
没有为std::unique_ptr<T>
定义输出运算符:它有点令人伤心,但许多C ++类缺少输出运算符。最简单的方法是只打印指针:
stream << bar.foo_unique().get();
如果你想打印实际的指针,或者你要取消引用指针
stream << *bar.foo_unique();
如果你想打印指针。
要使用输出运算符,您可以使用std::unique_ptr<Foo>
创建自己的输出运算符,假设Foo
是用户定义的类型。您将它放在与定义Foo
的名称空间相同的名称空间中:
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
}
答案 1 :(得分:0)
没有从std::unique_ptr<T>
到T const&
的隐式转换阻止了流插入运算符的确定。你有几个选择。第一个选项是为operator<<
提供一个std::unique_ptr<T>
覆盖,为T&
提供一个覆盖。如果您同时使用std::unique_ptr
和非拥有原始指针或引用,这可能会变得乏味。第二个选项是提供operator<<
的单个模板化版本来处理std::unique_ptr<T>
的实例,然后处理各个实例以处理T const&
。以下是如何实现此目的的示例。
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;
}