Не удается импортировать как sstream, так и iostream в С++ 20?

Создайте новое пустое консольное приложение C++ для Windows в Visual Studio 2022.

Добавьте файл «main.cppm» и заполните его следующим образом:

import <sstream>;

int main()
{
    std::stringstream ss;
    ss << "Hey world!";
    return 0;
}

Он должен компилироваться и работать нормально (хотя и не делает ничего полезного).

Теперь закомментируйте это и измените код на этот:

//import <sstream>;
import <iostream>;

int main()
{
    std::cout << "Hello world!" << std::endl;
    //std::stringstream ss;
    //ss << "Hey world!";
    return 0;
}

Опять же, он компилируется и работает нормально, и мы видим «Hello world!» на консоли.

Но теперь раскомментируйте закомментированные строки:

import <sstream>;
import <iostream>;

int main()
{
    std::cout << "Hello world!" << std::endl;
    std::stringstream ss;
    ss << "Hey world!";
    return 0;
}

Это НЕ скомпилируется, выдавая следующие ошибки:

E0070 неполный тип не допускается

(относится к stringstream)

E0349 ни один оператор "<<" не соответствует этим операндам

E3365 неполный тип класса "std::basic_stringstream<char, std::char_traits<char>, std::allocator<char>>" не разрешен

и следующее сообщение:

Локальная переменная не инициализирована

(имеется в виду переменная ss)

Он отлично компилируется, если я:

  1. #include <sstream> и import <iostream>;, или
  2. #include <iostream> и import <sstream>;, или
  3. #include <iostream> и #include <sstream>;.

Но Я НЕ МОГУ import <iostream>; и import <sstream>; одновременно.

Может ли кто-нибудь объяснить, почему, или знает, как импортировать оба? Я подозреваю, что это связано с зависимостью между ними, но я не уверен.

Диагностика Exxxx не является ошибкой компиляции, а просто извергается парсером Intellisense. Это очень новая функция, поэтому могут возникнуть проблемы, отправляйте отчеты об ошибках с помощью меню «Справка» > «Отправить отзыв».

Hans Passant 26.04.2023 04:42

Спасибо Ганс. Я довольно новичок в C++ и не был уверен, что делаю что-то не так.

Todd Burch 26.04.2023 04:52

Почему import и только #include заголовки для начала?

David C. Rankin 26.04.2023 06:54

@DavidC.Rankin Обзор модулей в C++

Remy Lebeau 26.04.2023 08:10

@ToddBurch большинство стандартных модулей библиотеки доступны через import std.core;

Remy Lebeau 26.04.2023 08:11

@RemyLebeau - спасибо. Дело в компиляторе MS. Я никогда не сталкивался с проблемой использования #include с cl.exe или gcc или любым другим компилятором, поэтому мне было немного любопытно, почему выбор одного над другим. Независимо скомпилированный набор исходников звучит интересно, хотя я немного не уверен в проблемах с заголовочными файлами, которые он должен лечить. Объясняет, почему g++ сразу же вырвало на источник :)

David C. Rankin 26.04.2023 08:17

@DavidC.Rankin, когда ваши проекты становятся большими, время компиляции становится чрезмерно медленным при использовании заголовков (а также становится очень неэффективным). Модули C++20 предназначены для решения этой (а также некоторых других проблем).

Todd Burch 26.04.2023 08:47

@RemyLebeau Мне еще не удалось заставить std.core работать, плюс я думаю, что импорт только используемых модулей лучше документирует потребности кода, но я могу в конечном итоге двигаться в этом направлении.

Todd Burch 26.04.2023 08:49

Я бы избегал модулей еще год или два, особенно если вы новичок в C++. Они еще не получили широкой/должной поддержки. Если у вас есть проблемы со временем сборки, убедитесь, что вы используете PCH.

HolyBlackCat 26.04.2023 09:19

Это заставляет задуматься о происхождении модулей, когда связанная страница объясняет: «До того, как это было указано в стандарте C++ 20, Microsoft имела экспериментальную поддержку модулей в компиляторе Microsoft C++». Хотя страница предупреждает, что для существующим более крупным существующим проектам, чтобы «основывать свое принятие на том, получите ли вы значимое сокращение времени компиляции». Будет неплохо поэкспериментировать и посмотреть, что может получиться.

David C. Rankin 26.04.2023 13:41

@ToddBurch: предполагается, что импорт компонентов стандартной библиотеки в виде блоков заголовков работает, но в большинстве реализаций он работает не очень хорошо.

Nicol Bolas 26.04.2023 15:49
Стоит ли изучать 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
11
326
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это явно ошибка в Visual Studio, особенно в IntelliSense. Обратите внимание, что поддержка модулей там все еще неполная, поэтому, пока она не будет исправлена, вам придется использовать include. В C++23 вы также сможете делать import std.

Нет, не с предоставленной информацией. Диагностика, начинающаяся с E, не из MSVC (они будут начинаться с C), а из IntelliSense, которая является функцией IDE, а не компилятором C++.

Fulgen 01.05.2023 21:22

@Fulgen Обратите внимание, что старая аббревиатура MSVC обычно (хотя, возможно, и неточно) используется для ссылки на всю среду разработки Visual Studio (которая включает IntelliSense), а не только на компилятор cl.exe, если вас беспокоит этот ответ.

Bob__ 01.05.2023 23:26

@Bob__ Хм, у меня тоже сложилось впечатление, что это относится к компилятору. Например, см. это или это.

HolyBlackCat 02.05.2023 08:46

Уточнено, что MSVC относится к VS, а не к компилятору.

vitaut 02.05.2023 16:11

MSVC обычно относится к набору инструментов Microsoft Visual C++: исходному компилятору. См., например, эту страницу, на которой используется аббревиатура. Немного сбивает с толку тот факт, что Visual Studio имеет несколько компиляторов C++: среда IDE (например, IntelliSense) использует другой компилятор C++. Использование «MSVC» для обозначения ошибки, проявляющейся именно в IDE, сбивает с толку.

apardoe 02.05.2023 16:41
Ответ принят как подходящий

Я тестировал MSVC 2022 версии 17.5.4 и 17.6.0 Предварительная версия 5.0.

Редактировать: IDE говорит, что поддержка С++ IntelliSense для модулей С++ 20 в настоящее время является экспериментальной.

Код компилируется и запускается.

Scan Sources for Module Dependencies должно быть Да.

Вы можете изменить этот параметр следующим образом:

Меню -> Проект -> Свойства -> Свойства конфигурации -> C/C++ -> Все параметры -> Scan Sources for Module Dependencies -> Да.

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