【问题标题】:Why is there no operator<< for std::unique_ptr?为什么 std::unique_ptr 没有 operator<<?
【发布时间】:2014-12-10 08:48:10
【问题描述】:

[util.smartptr.shared.io] 在 C++11 标准中要求 operator&lt;&lt; 用于 shared_ptrs:

template<class E, class T, class Y>
basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);

但是,除非我错过了它,否则我在 [unique.ptr] 中看不到任何类似的东西,并且 en.cppreference.com 上的参考同意。有没有理由 区别?

【问题讨论】:

  • 我不确定这个问题是否可以回答。原因是(还)没有人将它纳入标准,但这是你想听到的吗?
  • @KerrekSB 想必他只是想确认它与make_unique相似。
  • @KerrekSB 这实际上是一个答案。我认为问题是“这是有根本原因,还是只是疏忽?”
  • @Angew:嗯,目前的标准中没有记录的理由不包含这个,但你应该查看提议unique_ptr 的原始文件。我敢打赌,根本没有人想过添加这个功能。它甚至不是一个遗漏,而是一个不存在。该标准以小增量增长,通常是不连贯的,并且没有一些整体的一致性强制执行。如果您认为这不一致并且应该修复,请发送论文 :-) 下一次会议是在 5 月。
  • 注意,顺便说一下,operator&lt;&lt; 忽略删除器。在shared_ptr 中,删除器是类型擦除的,这会使operator&lt;&lt; 变得非常复杂。对于unique_ptr,序列化删除器更有意义,但这会不一致。

标签: c++ c++11 language-lawyer unique-ptr


【解决方案1】:

有区别的原因吗?

不,没有。就像make_unique 一样,这是一个“疏忽”,应该在将来添加(如果有人可以麻烦发送提案)。
同时你可以输出ptr.get(),或者 - 如果不害怕未定义的行为:

#if __cplusplus <= 201600 // Some time in future
namespace std {
    template <class E, class T, class Y, class D>
    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os,
                                     unique_ptr<Y, D> const& p) {
        return os << p.get();
    }
}
#endif

根据 [namespace.std] 未定义:

如果 C++ 程序添加声明或定义,则其行为未定义 命名空间std […] 除非 另有规定。

... 而上述内容在这件事上是不允许的。但是,这种未定义的行为很好,可以在没有任何影响的情况下调用。

【讨论】:

  • +1,但您可能想进一步了解 UB 是什么(以及它在实践中的危害/无害程度)。
  • @Angew 等等,那不是已经在 SO 上讨论过无数次了吗?我认为这对每个人来说都很常见......
  • 强制性无趣鼻恶魔参考。
  • @Columbo 您的来电。只需从某个人的 POV 中查看它,该人从 Google 获得这个问题和答案,甚至不是 SO 成员。
  • @leemes 因为这不适用于 ADL。 (即标准库的not work in templates like ostream_iterator)。
猜你喜欢
  • 2010-11-09
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
  • 2015-04-02
  • 2017-10-18
相关资源
最近更新 更多