可以将std :: getline()与std :: string一起使用吗? [英] Ok to use std::getline() with a moved-from std::string?

查看:86
本文介绍了可以将std :: getline()与std :: string一起使用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

第二个参数 <$ c $是否安全且定义明确? c> std :: getline(std :: istream& ;, std :: string&) 是一个左值,表示从 std :: string ,如果是,该字符串是否已还原从其移出状态开始,因此 pop_back( ) 可以安全地调用吗?



输入更简单,是否使用 getline写入字符串? )具有与分配给该字符串相同的语义?



或更具体地讲,以下(有些人为设计的)代码段是否定义正确?

  std :: ifstream f( foo.txt); 

std :: vector< std :: string>线;

for(std :: string s; std :: getline(f,s); lines.push_back(std :: move(s)))
if(!s.empty( )&& s.back()=='\r')
s.pop_back();

已优化( -march = native -O3 )使用 g ++ clang ++ 的此代码段的构建似乎可以正常工作,但这当然不能保证。 / p>

我想知道这是否仅依赖于根据 getline()在C ++ 11标准中,如果不是,则由该标准的更高版本很好地定义;或者,如果不是,则至少由任何/所有主要实现(G ++,Clang ++ ,Visual C ++,英特尔C ++编译器)。



NB:这是 不是 的重复问题,询问是否分配给移出的对象是安全的(是的,如果它是普通类型或STL类型),因为 getline()不是赋值运算符。

解决方案

您的代码是安全的,但这仅是因为您正在检查 getline 是否在其中成功存储了某些内容 s 。如果 getline 内部的哨兵未能初始化,则不会为<$​​ c $ c> s 分配任何东西,并将其保留在有效但未指定状态。只要 getline 成功将 s 设置为已知状态,就很好。



成功完成哨兵建设后, getline 要做的第一件事是将 s 设置为大小为零(已知状态)。



下面在GManNickG的评论中提供更多详细信息。


Is it safe and well-defined for the second argument to std::getline(std::istream&, std::string&) to be an lvalue referring to a moved-from std::string, and, if so, is that string restored from its moved-from state, so methods such as pop_back() can be safely invoked?

Put more simply, does writing to a string with getline() have equivalent semantics to assigning to that string?

Or more concretely, is the following (somewhat contrived) snippet well-defined and correct?

std::ifstream f("foo.txt");

std::vector<std::string> lines;

for (std::string s; std::getline(f, s); lines.push_back(std::move(s)))
        if (!s.empty() && s.back() == '\r')
                s.pop_back();

Optimized (-march=native -O3) builds of this snippet with g++ and clang++ appear to work as expected, but that is of course no guarantee.

I'd like to know if this is relying only on well-defined behavior according to the semantics of getline() in the C++11 standard, or, if not, if it's well-defined by a later edition of the standard, or, if not, if it's at least explicitly defined by any/all of the major implementations (G++, Clang++, Visual C++, Intel C++ Compiler).

NB: This is not a duplicate of previous questions asking whether it's safe to assign to a moved-from object (yes, if it's a trivial or STL type) because getline() is not the assignment operator.

解决方案

Your code is safe, but only because you are checking if the getline successfully stored something in s. If the sentry internal to getline failed to initialize, then nothing would be assigned to s and it would be left in the valid-but-unspecified state. As long as getline succeeds in setting s to a known state, you're good.

And the very first thing getline does after successful sentry construction is set s to a zero size (a known state).

More details below in GManNickG's comment.

这篇关于可以将std :: getline()与std :: string一起使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆