【问题标题】:Why the function std::basic_streambuf::setg() takes non-const agruments为什么函数 std::basic_streambuf::seth() 采用非常量参数
【发布时间】:2017-12-14 04:06:52
【问题描述】:

我正在检查 std::basic_streambuf 类中的函数 setg()。它在文件 streambuf 中定义。

gcc版本是5.4.0

我使用的编译选项是-std=gnu++14

void
setg(char_type* __gbeg, char_type* __gnext, char_type* __gend)
{
    _M_in_beg = __gbeg;
    _M_in_cur = __gnext;
    _M_in_end = __gend;
}

成员变量声明为:

char_type*      _M_in_beg;     ///< Start of get area.
char_type*      _M_in_cur;     ///< Current read area.
char_type*      _M_in_end;     ///< End of get area.
char_type*      _M_out_beg;    ///< Start of put area.
char_type*      _M_out_cur;    ///< Current put area.
char_type*      _M_out_end;    ///< End of put area.

我知道由于成员变量是非常量char_type*,所以函数setg()只能接受非常量参数。 但是这些指针的目的是检索东西,那些指针char_type * 应该首先声明为const char_type*,对吧?

因为成员变量指针是非常量指针,我会假设这些指针指向的值可以在某些特定情况下更改。

我的问题是basic_streambuf 对象在什么情况下会更改获取区域中的值?如果get area的内容不会改变,有没有理由不使用const指针cosnt char_type*

编辑 1
在这种情况下,成员变量可以声明为:

char_type const *_M_in_beg;     ///< Start of get area.
char_type const *_M_in_cur;     ///< Current read area.
char_type const *_M_in_end;     ///< End of get area.
char_type       *_M_out_beg;    ///< Start of put area.
char_type       *_M_out_cur;    ///< Current put area.
char_type       *_M_out_end;    ///< End of put area.

所以setg() 可以声明为:

void
setg(char_type const* __gbeg, char_type const* __gnext, char_type const* __gend)

关于这个问题的一些背景故事。我的同事修改了一个函数foo(),它调用setg(),所以输入参数是非常量的。但是foo()的输入参数不应该修改。由于参数setg() 是非常量。 foo() 的函数参数不能是 const。通过他的单元测试用例的修改但由于修改更改了输入值而使我的失败。如果 setg() 首先采用 const,世界会更好。
编辑结束 1

PS 当我再次阅读该函数时,变量名给我留下了深刻的印象,函数setg() 的第二个参数名为_gnext,它被分配给名为_M_in_cur 的指针,我几乎修改了我的代码以增加在传递给函数之前指向 1 的指针。为参数命名的人做得很好。

basic_streambuf reference

提前感谢您提供的任何解释

r0nG

【问题讨论】:

  • 您可以争辩说它们可以声明为char_type* const,但char_type const* 不起作用,因为它不能转换为char_type*
  • 在一个流中,get区域的开始和结束不对应流的开始和结束,而是本地缓冲区。在实践中,大多数流实现只使用一个获取缓冲区,因此这些边界不会改变,但它们可能在具有更复杂缓冲的流实现中。

标签: c++ pointers constants


【解决方案1】:

get 区域是一个缓冲区,用于从关联的输入序列中读取字符。如果调用了 read 方法但 get 区域中没有足够的字符,basic_streambuf 对象将读取关联的输入序列以更新 get 区域中的内容。在这种情况下,获取区域中的内容会被修改。

【讨论】:

  • 感谢您的回答。我更新了我的问题,以便更清楚。 AFAIU,获取区域只是指向关联流的 3 个指针。所以基本上我相信更新获取区域操作正在更改指针值以指向新位置。
  • @r0ng 无论如何,您应该将相关输入序列中的字符加载到这些指针指向的位置,并且此操作可能是通过这些指针完成的,因此它们不能定义为const char_type*。当然,可以通过其他指针或glvalues而不是这些指针来执行加载,或者只是让它们直接指向关联的输入序列,但标准不应将指针定义为const char_type* to force 这样做的实施。对于您的背景,我认为将您的论点用作这些指针不是一个好主意。
猜你喜欢
  • 2013-12-21
  • 1970-01-01
  • 2017-02-18
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
相关资源
最近更新 更多