Это скомпилировано нормально с моей версией clang, я думаю , что это может быть ошибка gcc.
Из моего прочтения стандарта, cout
является lvalue типа std::ostream
и ofstream("tmp.txt")
- это rvalue типа std::ofstream
.
Ни один из них не имеет cv-определителей , а std::ostream
- этобазовый класс std::ofstream
, поэтому условный оператор действителен, а результатом является rvalue и имеет тип std::ostream
.
Копирование ни одного из операндов не подразумевается.
, если E1
и E2
имеют тип класса, а базовые типы классов совпадают или один является базовым классом другого: E1
можно преобразовать в соответствие E2
, если классT2
- это тот же тип или базовый класс, что и класс T1
, а квалификация cv T2
- та же квалификация cv, что и квалификация cv или более высокая квалификация, чем cv-квалификация T1
.Если преобразование применяется, E1
изменяется на значение типа T2
, которое все еще ссылается на исходный объект класса источника (или соответствующий подобъект).[ Примечание: , то есть копия не создается.]
Используемая вами перегрузка operator<<
является членом std::ostream
, поэтому нет необходимости связывать временную ссылку с неконстантной ссылкой, элемент может быть вызван для неконстантной ссылки.-const rvalue .
basic_ostream<charT,traits>&
basic_ostream<charT,traits>::operator<< (basic_streambuf<charT,traits>* sb);
Редактировать
Обратите внимание, что это изменилось в C ++ 0x.Теперь, если результатом условного выражения является rvalue , всегда создается временная копия.Поскольку объекты типа ostream
не подлежат копированию, ваш код будет недействительным в C ++ 0x.
См. Здесь: http://www.open -std.org / jtc1 / sc22 / wg21 / docs /cwg_defects.html # 446