Создайте новое пустое консольное приложение 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
)
Он отлично компилируется, если я:
#include <sstream>
и import <iostream>;
, или#include <iostream>
и import <sstream>;
, или#include <iostream>
и #include <sstream>;
.Но Я НЕ МОГУ import <iostream>;
и import <sstream>;
одновременно.
Может ли кто-нибудь объяснить, почему, или знает, как импортировать оба? Я подозреваю, что это связано с зависимостью между ними, но я не уверен.
Спасибо Ганс. Я довольно новичок в C++ и не был уверен, что делаю что-то не так.
Почему import
и только #include
заголовки для начала?
@DavidC.Rankin Обзор модулей в C++
@ToddBurch большинство стандартных модулей библиотеки доступны через import std.core;
@RemyLebeau - спасибо. Дело в компиляторе MS. Я никогда не сталкивался с проблемой использования #include
с cl.exe
или gcc
или любым другим компилятором, поэтому мне было немного любопытно, почему выбор одного над другим. Независимо скомпилированный набор исходников звучит интересно, хотя я немного не уверен в проблемах с заголовочными файлами, которые он должен лечить. Объясняет, почему g++
сразу же вырвало на источник :)
@DavidC.Rankin, когда ваши проекты становятся большими, время компиляции становится чрезмерно медленным при использовании заголовков (а также становится очень неэффективным). Модули C++20 предназначены для решения этой (а также некоторых других проблем).
@RemyLebeau Мне еще не удалось заставить std.core работать, плюс я думаю, что импорт только используемых модулей лучше документирует потребности кода, но я могу в конечном итоге двигаться в этом направлении.
Я бы избегал модулей еще год или два, особенно если вы новичок в C++. Они еще не получили широкой/должной поддержки. Если у вас есть проблемы со временем сборки, убедитесь, что вы используете PCH.
Это заставляет задуматься о происхождении модулей, когда связанная страница объясняет: «До того, как это было указано в стандарте C++ 20, Microsoft имела экспериментальную поддержку модулей в компиляторе Microsoft C++». Хотя страница предупреждает, что для существующим более крупным существующим проектам, чтобы «основывать свое принятие на том, получите ли вы значимое сокращение времени компиляции». Будет неплохо поэкспериментировать и посмотреть, что может получиться.
@ToddBurch: предполагается, что импорт компонентов стандартной библиотеки в виде блоков заголовков работает, но в большинстве реализаций он работает не очень хорошо.
Это явно ошибка в Visual Studio, особенно в IntelliSense. Обратите внимание, что поддержка модулей там все еще неполная, поэтому, пока она не будет исправлена, вам придется использовать include. В C++23 вы также сможете делать import std
.
Нет, не с предоставленной информацией. Диагностика, начинающаяся с E, не из MSVC (они будут начинаться с C), а из IntelliSense, которая является функцией IDE, а не компилятором C++.
@Fulgen Обратите внимание, что старая аббревиатура MSVC обычно (хотя, возможно, и неточно) используется для ссылки на всю среду разработки Visual Studio (которая включает IntelliSense), а не только на компилятор cl.exe
, если вас беспокоит этот ответ.
@Bob__ Хм, у меня тоже сложилось впечатление, что это относится к компилятору. Например, см. это или это.
Уточнено, что MSVC относится к VS, а не к компилятору.
MSVC обычно относится к набору инструментов Microsoft Visual C++: исходному компилятору. См., например, эту страницу, на которой используется аббревиатура. Немного сбивает с толку тот факт, что Visual Studio имеет несколько компиляторов C++: среда IDE (например, IntelliSense) использует другой компилятор C++. Использование «MSVC» для обозначения ошибки, проявляющейся именно в IDE, сбивает с толку.
Я тестировал 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
-> Да.
Диагностика Exxxx не является ошибкой компиляции, а просто извергается парсером Intellisense. Это очень новая функция, поэтому могут возникнуть проблемы, отправляйте отчеты об ошибках с помощью меню «Справка» > «Отправить отзыв».