Auto open_flags = std::ios::binary; кажется, создает неправильный тип в MSVC. Это ошибка?

Этот код 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 или я что-то упустил? Ссылки на стандарты приветствуются!

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это ошибка MSVC.

Согласно стандарту:

  1. binary имеет тип std::ios_base::openmode ([ios.base.general]);
  2. std::ios_base::openmode — это тип битовой маски ([ios.openmode]).

Но на MSVC:

  1. binary имеет тип enum (внутренний тип _Openmode) , но std::ios_base::openmode — это int.
  2. _Openmode не является типом битовой маски (поэтому применимы только встроенные операторы |, &, ^, ~).

Пожалуйста, отправьте отчет об ошибке (или два) по адресу https://github.com/microsoft/STL.

Отчет об ошибке отправлен, спасибо. Должен быть интересный опыт. К счастью, это кажется самой простой ошибкой, с которой я мог надеяться столкнуться ;-). github.com/microsoft/STL/issues/3401

Neil Stephens 11.02.2023 00:10

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

Проблема со списком инициализаторов в конструкторе
Почему в С++ есть это правило: явные определения создания экземпляров игнорируют спецификаторы доступа к членам: типы параметров и возвращаемые типы могут быть закрытыми
Модель памяти «получить-освободить» для двух последовательных атомарных операций
Стандарт С++ для смещений элементов стандартной структуры макета
Почему в этом примере используется «2.» вместо «2.0» (десятичная точка без десятичных знаков)?
Используйте лямбда через ссылку std::function, вы не можете изменить значение в лямбда
Виртуальный метод в С++ не высмеивается. Что мне здесь не хватает?
=default и =delete - это объявление функции или определение функции?
Почему попытка напечатать строки в кодировке Unicode с помощью cout приводит к ошибке компиляции в новых стандартах C++?
Decltype оценивает неверный тип из списка выражений