字符串流运算符>>作为函数失败,但作为实例工作?
我正在编写简单的代码,将从文件中提取一堆名称、整数对。我正在修改仅使用的现有代码:
string chrom;
unsigned int size;
while ( cin >> chrom >> size ) {
// save values
}
但我想使用另一个(类似的)输入文件,该文件具有相同的前两列,但后面跟着其他数据(将被忽略)。 所以我写:
string chrom;
unsigned int size;
string line;
while ( getline(cin, line) ) {
if( stringstream(line) >> chrom >> size ) {
// save values
}
}
但这无法编译,给出典型的淫秽 std lib 模板喷出:
error: no match for "operator>>" in "std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >(((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >*)(& line))), std::operator|(_S_out, _S_in)) >> chrom"
istream:131: note: candidates are: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>& (*)(std::basic_istream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
[...another dozen lines...]
对。 line 不是 std::string,而是 std::basic_string 的一些变体,等等。 但是,显式实例化 stringstream 是可行的。
string chrom;
unsigned int size;
string line;
while ( getline(genome, line) ) {
stringstream ss(line);
if ( ss >> chrom >> size ) {
// save values
}
// Discard remainder of line
}
为什么?第一种情况有什么问题?始终有用的 cplusplus.com 上的示例 basic_io 有效,为什么我的不起作用代码?
更新: 另一个参考点:当提取的第一个值是 int 而不是字符串时,临时字符串流起作用:
unsigned int chrom; // works as int...
unsigned int size;
string line;
while ( getline(cin, line) ) {
if( stringstream(line) >> chrom >> size ) {
// save values
}
}
I'm writing simple code that will extract a bunch of name, int pairs from a file. I'm modifying existing code that just uses:
string chrom;
unsigned int size;
while ( cin >> chrom >> size ) {
// save values
}
But I want to use another (similar) input file that has the same first two columns, but are followed by other data (that will be ignored).
So I write:
string chrom;
unsigned int size;
string line;
while ( getline(cin, line) ) {
if( stringstream(line) >> chrom >> size ) {
// save values
}
}
But this fails to compile, giving the typical obscene std lib template spew:
error: no match for "operator>>" in "std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >(((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >*)(& line))), std::operator|(_S_out, _S_in)) >> chrom"
istream:131: note: candidates are: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>& (*)(std::basic_istream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
[...another dozen lines...]
Right. line isn't a std::string, but some variation of std::basic_string, etc.
However, explicitly instantiating the stringstream works.
string chrom;
unsigned int size;
string line;
while ( getline(genome, line) ) {
stringstream ss(line);
if ( ss >> chrom >> size ) {
// save values
}
// Discard remainder of line
}
Why? What is wrong with the first case? The example basic_io at the always helpful cplusplus.com works, why doesn't my code?
Update:
Another point of reference: the temporary stringstream works when the first value extracted is an int instead of a string:
unsigned int chrom; // works as int...
unsigned int size;
string line;
while ( getline(cin, line) ) {
if( stringstream(line) >> chrom >> size ) {
// save values
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
C和C++中的一些运算符要求运算符左边的值是左值,即它们可以被修改。
此处 是更完整的解释。
Some operators in C and C++ require that the value on the left of the operator be an lvalue, i.e. that they can be modified.
Here is a more complete explanation.
因为从 stringstream 中提取的第一个值是 std::string。如果它是一个 int,那么 stringstream(line) 版本就可以工作。
没有成员函数运算符>>在 std::string 的 stringstream 中。因此,临时流不能充当左值。
并不是说我完全理解上述内容......但也许这是一个更好答案的起点。
Because the first value extracted from the stringstream is a std::string. If it was, say, an int, the stringstream(line) version would work.
There's no member function operator>> in stringstream for std::string. Therefore, the temporary stream cannot function as an lvalue.
Not that I fully understand the above... but perhaps it's a starting place for a better answer.
三组成员函数和一组全局函数重载了这个“提取运算符”(>>),参见http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/。
当“chrom”为int时,运算符>>被重载为算术提取器,它是成员函数。普通对象或临时对象都可以正常工作。
当“chrom”为字符串时,运算符>>应该重载为
istream&运算符>> (istream& is, char* str)
,这是一个全局函数,应该以对象引用作为参数。然而,对于给定的临时对象,我们不允许在标准 C++ 中通过非常量引用来传递临时对象。重载函数无法获取临时对象的引用,除非重载函数定义为 istream&运算符>> (const istream& is, char* str)。不幸的是,事实并非如此。在临时对象的情况下,函数无法重载,因此会发出类似error: no match for function...
的错误Three groups of member functions and one group of global functions overload this "extraction operator" (>>), see http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/.
when "chrom" is int, operator >> is overloaded as arithmetic extractor which is member functions. Both the normal object or temporary object work fine.
When "chrom" is string, operator >> should be overloaded as
istream& operator>> (istream& is, char* str)
, this is a global functions which should take the object reference as parameter. However, given temporary object, we are not allowed to pass temporary objects by non-const reference in standard C++. The overload function cannot get the reference of the temporary object unless the overload function is defined asistream& operator>> (const istream& is, char* str)
. Unfortunately, that is not the fact. The function(s) cannot be overloaded in the temporary object case, and hence giving out the error likeerror: no match for function...
为了扩展 John Weldon 的答案,额外运算符“>>”做两件事:
因此,它同时修改其左操作数和右操作数。在您的情况下,左侧操作数是一个临时值,编译器不赞成修改它。
To expand on John Weldon's answer, the extrace operator ">>" does two things:
Therefore, it modifies both its left and right operand. In your case, the left-hand operand is a temporary value, and the compiler frowns on modifying it.