【问题标题】:what is the real return type of std::setw, std::setfill and so on?std::setw、std::setfill 等的真正返回类型是什么?
【发布时间】:2018-02-24 00:27:42
【问题描述】:

我很好奇 std::setw 和 std::setfill 的真正返回类型

正如我们看到的引用,它们的返回值数据类型是“未定义”。 但是,是否可以声明一个没有返回类型的函数?

在我必须开发一种为“cout”或“cin”提供扩展功能的方法的情况下, 这个方法应该像

cout << foo(32, 'A', 0.00f) << "Hello world!";

我应该如何声明方法?

【问题讨论】:

  • 该方法应该返回一个std::ostream。此外,std::setw 具有未指定的返回类型(它的实现已定义)
  • @Brandon:不,不应该。 operator&lt;&lt; 返回 ostream,但 setwsetfill 不返回。
  • @Brandon:ostream 究竟应该foo 返回什么?
  • @Brandon:为什么要返回cout?那会实现什么?
  • @BenjaminLindley“未指定”不同于“实现定义”

标签: c++


【解决方案1】:

std::setw et al 的返回类型未指定,因为每个 C++ 实现可能会决定以不同的方式执行此操作,因此没有一个答案 - 您必须调查您感兴趣的编译器/版本。

查看与 GCC 一起使用的 libstdc++,我们看到:

00214   struct _Setw { int _M_n; };
00215 
00216   /**
00217    *  @brief  Manipulator for @c width.
00218    *  @param  n  The new width.
00219    *
00220    *  Sent to a stream object, this manipulator calls @c width(n) for
00221    *  that object.
00222   */
00223   inline _Setw 
00224   setw(int __n)
00225   { return { __n }; } 

_Setw 是一个用于捕获宽度参数的小结构,然后std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, _Setw)...&gt;&gt;... 可以处理它来设置流中的宽度:

00227   template<typename _CharT, typename _Traits>
00228     inline basic_istream<_CharT, _Traits>& 
00229     operator>>(basic_istream<_CharT, _Traits>& __is, _Setw __f)
00230     {
00231       __is.width(__f._M_n);
00232       return __is; 
00233     }
00234 
00235   template<typename _CharT, typename _Traits>
00236     inline basic_ostream<_CharT, _Traits>& 
00237     operator<<(basic_ostream<_CharT, _Traits>& __os, _Setw __f)
00238     {
00239       __os.width(__f._M_n);
00240       return __os; 
00241     }

正如我们看到的引用,它们的返回值数据类型是“未定义”。

它是未指定,而不是未定义。

但是,是否可以声明一个没有返回类型的函数?

否 - 每个函数都必须有一个返回类型,即使只有 void

在我必须开发一种为“cout”或“cin”提供扩展功能的方法的情况下,应该像这样调用此方法

cout << foo(32, 'A', 0.00f) << "Hello world!";

我应该如何声明方法?

您可以做类似的事情,让函数foo 返回一个您为其编写流式操作符的对象。然后,这些流函数应该操纵流:您需要使用 iwordxalloc 为流提供额外的状态,以跟踪您要添加的可能修改的行为 - 请参阅 this answer

【讨论】:

  • 那么,如果我必须开发“foo”方法来让下面的文字看起来不一样,我该怎么办? // 例如cout
  • 在我的回答中查看刚刚附加的信息。干杯
  • 我明白了。谢谢你的好意回答。祝你有美好的一天!
  • @LucianoJeong 如果你对这个答案感到满意,你应该接受它(绿色勾号)。
【解决方案2】:

它是未指定的,或者换句话说,未在 C++ 标准中指定,并且取决于您的库实现。更多关于 here.

您不能声明自己的函数来操作插入/提取运算符,除非您重载它们以接受新类型。

【讨论】:

    猜你喜欢
    • 2017-07-20
    • 1970-01-01
    • 2013-07-10
    • 2012-08-27
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多