开发者

stringstream operator>> fails as function, but works as instance?

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开发者_如何学C 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
    }
}


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


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜