可以将std :: getline()与std :: string一起使用吗? [英] Ok to use std::getline() with a moved-from 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屋!