Этот код C++ отлично компилируется с gcc, icc и clang, но не работает с MSVC:
#include <ios>
int main()
{
auto open_flags = std::ios::binary;
open_flags |= std::ios::app;
return 0;
}
(6): ошибка C2678: двоичный файл '|=': не найден оператор, который принимает левый операнд типа 'std::_Iosb::_Openmode' (или нет приемлемого преобразования)
https://godbolt.org/z/999fffPEx
Изменение кода на это дает более полезное сообщение об ошибке:
#include <ios>
int main()
{
auto open_flags = std::ios::binary;
open_flags = open_flags | std::ios::app;
return 0;
}
(6): ошибка C2440: '=': невозможно преобразовать из 'int' в 'std::_Iosb::_Openmode'
И это прекрасно компилируется:
#include <ios>
int main()
{
auto open_flags = std::ios::binary | std::ios::out;
open_flags = open_flags | std::ios::app;
return 0;
}
Это выглядит как неправильное поведение для меня. Подобно тому, как MSVC реализовал | оператор с типом возвращаемого значения int вместо ios::openmode.
Также стоит отметить, что исходный код компилируется, если я использую std::ios::openmode вместо auto, предположительно посредством неявного преобразования.
Это ошибка MSVC или я что-то упустил? Ссылки на стандарты приветствуются!
Это ошибка MSVC.
Согласно стандарту:
binary
имеет тип std::ios_base::openmode
([ios.base.general]);std::ios_base::openmode
— это тип битовой маски ([ios.openmode]).Но на MSVC:
_Openmode
не является типом битовой маски (поэтому применимы только встроенные операторы |
, &
, ^
, ~
).Пожалуйста, отправьте отчет об ошибке (или два) по адресу https://github.com/microsoft/STL.
Отчет об ошибке отправлен, спасибо. Должен быть интересный опыт. К счастью, это кажется самой простой ошибкой, с которой я мог надеяться столкнуться ;-). github.com/microsoft/STL/issues/3401