【问题标题】:ostream on a std::unique_ptr class memberstd::unique_ptr 类成员上的 ostream
【发布时间】:2015-01-11 23:01:20
【问题描述】:

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

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

编辑:我想要流

【问题讨论】:

  • 对于 341 信誉,您提供这样的错误描述并不好!
  • 1) const std::unique_ptr&lt;Foo&gt;&amp; foo_unique() const 应该做什么(准确地说)?为什么除了Foo const&amp; foo() const还需要? 2) stream &lt;&lt; bar.foo_unique(); 应该做什么?
  • 对不起,缺少精确流
  • 如果你写stream &lt;&lt; *bar.foo_unique();,你会得到完全相同的行为。如果您不想编写额外的*,则需要定义另一个operator&lt;&lt;

标签: c++ c++14 unique-ptr


【解决方案1】:

没有为std::unique_ptr&lt;T&gt; 定义输出操作符:有点遗憾,但许多 C++ 类都缺少输出操作符。最简单的方法是打印指针:

stream << bar.foo_unique().get();

如果您想打印实际的指针或者取消引用指针

stream << *bar.foo_unique();

如果你想打印指针。

要使用输出运算符,您可以使用std::unique_ptr&lt;Foo&gt; 创建自己的输出运算符,假设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
}

【讨论】:

  • 谢谢你 stream 以想要的方式工作。但是,添加最后一个代码会给我 error: invalid initialization of reference of type ‘std::ostream&
  • 他忘记了out &lt;&lt;。返回语句应为:return out &lt;&lt; *foo;
  • @leemes: true - 不测试代码的危险!感谢修复!
  • "没有为std::unique_ptr&lt;T&gt;定义输出运算符" - C++20 adds one now
【解决方案2】:

没有从std::unique_ptr&lt;T&gt;T const&amp; 的隐式转换,这阻止了流插入运算符的确定。不过,您有几个选择。第一个选项是为std::unique_ptr&lt;T&gt;T&amp; 提供一个覆盖operator&lt;&lt;。如果您同时使用 std::unique_ptr 和非拥有的原始指针或引用,这可能会变得乏味。第二种选择是提供operator&lt;&lt; 的单个模板版本来处理std::unique_ptr&lt;T&gt; 的实例,然后提供单独的版本来处理T const&amp;。以下是如何完成此操作的示例。

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;
}

【讨论】:

  • “防止推导流插入算子” 推导如模板参数推导
猜你喜欢
  • 1970-01-01
  • 2017-01-15
  • 2022-01-12
  • 2015-07-16
  • 1970-01-01
  • 1970-01-01
  • 2013-08-07
  • 1970-01-01
  • 2015-04-15
相关资源
最近更新 更多