std::unique_ptr class 成员上的 ostream

ostream on a std::unique_ptr class member

我想打印一个 std::unique_ptr,它是 Bar 的 class 成员。 但是,以下代码不起作用,请参阅我对 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;
}

我怎样才能正确地做到这一点?

编辑:我想要流 << bar.foo_unique();具有与流相同的行为 << bar.foo();

没有为 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
}

没有从 std::unique_ptr<T>T const& 的隐式转换,这会阻止确定流插入运算符。不过,您在这里有几个选择。第一个选项是为 std::unique_ptr<T> 提供一个 operator<< 的覆盖,为 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;
}