Создание объекта ifstream без использования переменной - PullRequest
4 голосов
/ 05 ноября 2011

Я не могу открыть файл, не сохранив его в переменной.Я могу сделать это:

ifstream blob("somefile");
string line;
blob >> line;

Но когда я пытаюсь это сделать:

string line;
ifstream("somefile") >> line;

Компилятор (clang) выдает эту ошибку:

t.cpp:7:23: error: invalid operands to binary expression ('ifstream' (aka 'basic_ifstream<char>') and 'string' (aka 'basic_string<char>'))
    ifstream("thing") >> i;
    ~~~~~~~~~~~~~~~~~ ^  ~
In file included from t.cpp:1:
In file included from /usr/include/c++/4.6/iostream:39:
In file included from /usr/include/c++/4.6/ostream:39:
In file included from /usr/include/c++/4.6/ios:42:
In file included from /usr/include/c++/4.6/bits/ios_base.h:42:
In file included from /usr/include/c++/4.6/bits/locale_classes.h:41:
In file included from /usr/include/c++/4.6/string:53:
/usr/include/c++/4.6/bits/basic_string.h:2679:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>] not
      viable: no known conversion from 'ifstream' (aka 'basic_ifstream<char>') to 'basic_istream<char> &' for 1st argument
    operator>>(basic_istream<char>& __is, basic_string<char>& __str);
    ^
In file included from t.cpp:1:
In file included from /usr/include/c++/4.6/iostream:40:
/    usr/include/c++/4.6/istream:121:7: note: candidate function not viable: no known conversion from 'string' (aka 'basic_string<char>') to
      '__istream_type &(*)(__istream_type &)' for 1st argument
      operator>>(__istream_type& (*__pf)(__istream_type&))
      ^
/usr/include/c++/4.6/istream:125:7: note: candidate function not viable: no known conversion 

... a few more hundred pages of crap ...

1 error generated.

Итак, чторазница между двумя?С другими классами вызов его напрямую работает просто отлично.Есть ли какая-то магия шаблона, которая делает его неоднозначным?

1 Ответ

3 голосов
/ 05 ноября 2011

Код, который вы публикуете, недопустим в C ++ 03 (то есть, каким был языковой стандарт C ++ до сентября 2011 года).В C ++ 03 есть только одна перегрузка operator>>, которая может быть рассмотрена здесь [я удалил весь код шаблона, потому что он не релевантен]:

istream& operator>>(istream&, string&);

Обратите внимание, что *Параметр 1005 * является неконстантной ссылкой, поэтому временный объект std::istream использовать нельзя.В вашем коде вы пытаетесь использовать временный объект там.

В C ++ 11 (т. Е. В текущем стандарте языка C ++) существует дополнительная перегрузка, которая принимает объект std::istream по ссылке rvalue,Это позволяет либо передать временное значение через этот параметр.

Visual C ++ уже поддерживает эту функцию C ++ 11, поэтому, как указывает Бенджамин Линдли в комментарии, ваш код действительно скомпилируется, если выиспользуйте Visual C ++ 2010 или более позднюю версию.Ваша сборка Clang может поддерживать это, если вы используете флаг -std = c ++ 0x .

...