3

我正在编写简单的代码,它将从文件中提取一堆名称、整数对。我正在修改仅使用的现有代码:

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有效,为什么我的代码不起作用?

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
    }
}
4

4 回答 4

2

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.

于 2009-11-30T23:22:23.860 回答
2

To expand on John Weldon's answer, the extrace operator ">>" does two things:

  1. Extracts the next value and places it into the variable on the right of the operator.
  2. Increments the current position of the stream on the left.

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.

于 2009-11-30T23:50:47.687 回答
2

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/.

  • stringstream(line); --created a temporary object
  • stringstream ss(line);-- a normal object.

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 as istream& 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 like error: no match for function...

于 2013-02-12T16:51:10.197 回答
1

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.

于 2009-11-30T23:25:14.027 回答