Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 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
    }
}
like image 627
jmanning2k Avatar asked Mar 15 '26 19:03

jmanning2k


1 Answers

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

like image 74
Shasha.Zhu Avatar answered Mar 17 '26 08:03

Shasha.Zhu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!