оператор stringstream>> завершается с ошибкой как функция, но работает как экземпляр?

StackOverflow https://stackoverflow.com/questions/1823073

  •  10-07-2019
  •  | 
  •  

Вопрос

Я пишу простой код, который извлечет кучу пар name, int из файла.Я модифицирую существующий код, который просто использует:

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

Правильно.строка - это не 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
}

Почему?Что не так с первым случаем?В пример basic_io в разделе всегда полезно cplusplus.com работает, почему не работает мой код?

Обновить:Еще одна точка отсчета:временный stringstream работает, когда первое извлеченное значение является int вместо string:

unsigned int chrom;  // works as int...
unsigned int size;
string line;
while ( getline(cin, line) ) {
    if( stringstream(line) >> chrom >> size ) {
        // save values
    }
}
Это было полезно?

Решение

Три группы функций-членов и одна группа глобальных функций перегружают этот "оператор извлечения" (>>), см. http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/.

  • stringstream(строка);--создан временный объект
  • stringstream ss(строка);-- обычный объект.

когда "chrom" имеет значение int, operator >> перегружается как арифметический экстрактор, который является функциями-членами.Как обычный объект, так и временный объект работают нормально.

Когда "chrom" является строкой, оператор >> должен быть перегружен как istream& operator>> (istream& is, char* str), это глобальная функция, которая должна принимать ссылку на объект в качестве параметра.Однако, учитывая временный объект, нам не разрешается передавать временные объекты по неконстантной ссылке в стандартном C ++.Функция перегрузки не может получить ссылку на временный объект, если функция перегрузки не определена как istream& operator>> (const istream& is, char* str).К сожалению, это не факт.Функция (ы) не может быть перегружена в случае временного объекта и, следовательно, выдает ошибку типа error: no match for function...

Другие советы

Чтобы расширить ответ Джона Уэлдона, оператор extrace ">>" выполняет две вещи:

  1. Извлекает следующее значение и помещает его в переменную справа от оператора.
  2. Увеличивает текущее положение потока слева.

Следовательно, он изменяет как свой левый, так и правый операнд.В вашем случае левый операнд является временным значением, и компилятор не одобряет его изменение.

Некоторые операторы в C и C ++ требуют, чтобы значение слева от оператора было значением lvalue, т. е.что они могут быть изменены.

Здесь это более полное объяснение.

Потому что первое значение, извлеченное из stringstream, является std::string .Если бы это был, скажем, int, версия stringstream (строка) работала бы.

В stringstream для std::string нет оператора функции-члена>>.Следовательно, временный поток не может функционировать как значение lvalue.

Не то чтобы я полностью понимал вышесказанное...но, возможно, это отправная точка для лучшего ответа.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top