Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Megtudhatja, hogyan importálhatja a C++ standard kódtárat C++ kódtármodulok használatával. Ez gyorsabb fordítást eredményez, és robusztusabb, mint a fejlécfájlok, fejlécegységek vagy előre összeállított fejlécek (PCH) használata.
Ebben az oktatóanyagban a következőket ismerheti meg:
- A standard kódtár importálása modulként a parancssorból.
- A modulok teljesítmény- és használhatósági előnyei.
- A két standard kódtármodul
stdésstd.compata köztük lévő különbség.
Előfeltételek
Ehhez az oktatóanyaghoz a Visual Studio 2022 17.5-ös vagy újabb verziójára van szükség.
A standard kódtármodulok bemutatása
A fejlécfájl szemantikája a makródefinícióktól, a belefoglalásuk sorrendjétől és a fordítás lassúságától függően változhat. A modulok megoldják ezeket a problémákat.
Mostantól a standard könyvtár modulként importálható ahelyett, hogy fejlécfájlok kuszaságaként kezelnénk. Ez sokkal gyorsabb és robusztusabb, mint a fejlécfájlok, fejlécegységek vagy előre összeállított fejlécek (PCH).
A C++23 standard kódtár két nevesített modult vezet be: std és std.compat:
-
stdexportálja a C++ standard kódtár névterébenstddefiniált deklarációkat és neveket, példáulstd::vector. Emellett exportálja a C burkolófejek tartalmát is, például<cstdio>és<cstdlib>, amelyek olyan függvényeket biztosítanak, mint astd::printf(). A globális névtérben definiált C-függvények, például::printf()a , nem lesznek exportálva. Ez javítja azt a helyzetet, amikor egy C burkoló fejléc például<cstdio>is C fejlécfájlokat tartalmaz, mint példáulstdio.h, amelyek a C globális névtér változatait is magukkal hozzák. Ez nem jelent problémát az importáláskorstd. -
std.compatmindent exportál astd-ban, és hozzáadja a C futtatási környezet globális névtereit, például az::printf,::fopen,::size_t,::strlenés így tovább. Astd.compatmodul megkönnyíti a globális névtérben található számos C futtatókörnyezeti függvényre/típusra hivatkozó kódbázisok használatát.
A fordító a teljes standard könyvtárat importálja, amikor ön a import std; vagy import std.compat; használja, és ezt gyorsabban hajtja végre, mint egyetlen fejlécfájl betöltése esetén. Gyorsabb, ha például a teljes standard könyvtárat import std; (vagy import std.compat) használatával importáljuk, mint #include <vector>.
Mivel a nevesített modulok nem teszik elérhetővé a makrókat, például a assert, errno, offsetof, va_arg és más makrók nem érhetők el, amikor importálja a std vagy std.compat modulokat. A megoldásokért tekintse meg a A standard könyvtár elnevezett moduljainak szempontjai.
Tudnivalók a C++ modulokról
A fejlécfájlok a deklarációk és definíciók megosztásának módját képezik a C++-ban található forrásfájlok között. A szabványos kódtármodulok előtt a szükséges standard kódtár részét is belefoglalná egy olyan irányelvbe, mint a #include <vector>. A fejlécfájlok törékenyek és nehezen írhatók, mert szemantikáik a belefoglalásuk sorrendjétől vagy bizonyos makrók definiálásától függően változhatnak. A fordítás is lassú, mert minden olyan forrásfájl újra feldolgozta őket, amely tartalmazza őket.
A C++20 egy modern, moduloknak nevezett alternatívát vezet be. A C++23-ban a modultámogatást kihasználva elnevezett modulokat vezettünk be, amelyek a standard kódtárat képviselik.
A fejlécfájlokhoz hasonlóan a modulok lehetővé teszik a deklarációk és definíciók megosztását a forrásfájlok között. A fejlécfájlokkal ellentétben azonban a modulok nem törékenyek, és könnyebben írhatók, mert a szemantikák nem változnak a makródefiníciók vagy az importálásuk sorrendje miatt. A fordító sokkal gyorsabban tudja feldolgozni a modulokat, mint a #include fájlokat, és kevesebb memóriát használ fordításkor. A nevesített modulok nem teszik közzé a makródefiníciókat és a privát megvalósítás részleteit.
Ez a cikk bemutatja a standard kódtár felhasználásának új és legjobb módját. A standard kódtár használatának alternatív módjairól további információt a fejlécegységek, modulok és előre összeállított fejlécek összehasonlítása című témakörben talál.
A standard kódtár importálása a következővel: std
Az alábbi példák bemutatják, hogyan használhatja a standard kódtárat modulként a parancssori fordító használatával. Ennek a Visual Studio IDE-ben való használatáról az ISO C++23 Standard kódtármodulok buildelése című témakörben olvashat.
Az utasítás import std; vagy import std.compat; a standard könyvtárat importálja az alkalmazásba. Először azonban bináris formában kell lefordítania a standard kódtár nevesített moduljait. Az alábbi lépések bemutatják, hogyan.
Példa: Felépítés és importálás std
Nyisson meg egy x86 natív eszközök parancssort a VS-hez: a Windows Start menüben írja be az x86 natív típust , és a parancssornak szerepelnie kell az alkalmazások listájában. Győződjön meg arról, hogy az előugró ablak a Visual Studio 2022 17.5-ös vagy újabb verziójára vonatkozik. Ha a prompt rossz verzióját használja, hibákat kap. Az oktatóanyagban használt példák a CMD parancssorhoz készültek.
Hozzon létre egy könyvtárat, például
%USERPROFILE%\source\repos\STLModules, és állítsa be aktuális könyvtárként. Ha olyan könyvtárat választ, amelyhez nem rendelkezik írási hozzáféréssel, a fordítás során hibaüzenetek jelennek meg.Fordítsa le a
stdmegnevezett modult a következő paranccsal:cl /std:c++latest /EHsc /nologo /W4 /c "%VCToolsInstallDir%\modules\std.ixx"Ha hibaüzenetet kap, győződjön meg arról, hogy a parancssor megfelelő verzióját használja.
Fordítsa le a
stdmegnevezett modult ugyanazokkal a fordítóbeállításokkal, amelyeket a beépített modult importáló kóddal használni kíván. Ha többprojektes megoldással rendelkezik, egyszer lefordíthatja a standard könyvtár-modult, majd az összes projektből hivatkozhat rá a/referencekapcsoló segítségével.Az előző fordítóparancs használatával a fordító két fájlt ad ki:
-
std.ifcazon elnevezett modulfelület lefordított bináris reprezentációja, amelyet a fordító azimport std;utasítás feldolgozásához szükséges konzultációként használ. Ez csak fordítási idejű összetevő. Nem része az alkalmazás csomagjának. -
std.objtartalmazza a megnevezett modul implementációját. A mintaalkalmazás lefordításakor vegye felstd.obja parancssorba, hogy statikusan összekapcsolja a standard kódtárból használt funkciókat az alkalmazással.
A példában szereplő fő parancssori kapcsolók a következők:
Kapcsoló Meaning /std:c++latestHasználja a C++ nyelvi szabvány és a kódtár legújabb verzióját. Bár a modultámogatás a következő területen /std:c++20érhető el, a standard kódtár nevesített modulok támogatásához a legújabb standard kódtárra van szüksége./EHscC++ kivételkezelés használata a megjelölt extern "C"függvények kivételével./W4A használat /W4általánosan ajánlott, különösen az új projektek esetében, mivel lehetővé teszi az 1. szint, a 2. szint, a 3. szint és a legtöbb 4. szintű (tájékoztató) figyelmeztetést, ami segíthet a potenciális problémák korai észlelésében. Lényegében lint-szerű figyelmeztetéseket biztosít, amelyek segítenek biztosítani a lehető legkevesebb nehezen kereshető kódhibát./cFordítás csatolás nélkül, mert jelenleg csak a bináris elnevezett modul felületét készítjük el. Az objektumfájl nevét és a modul felületének nevét a következő kapcsolókkal szabályozhatja:
-
/Foaz objektumfájl nevét állítja be. Például:/Fo:"somethingelse". Alapértelmezés szerint a fordító ugyanazt a nevet használja az objektumfájlhoz, mint a modul forrásfájlja (.ixx) amelyet összeállít. A példában az objektumfájl neve alapértelmezés szerint azért vanstd.obj, mert a modulfájltstd.ixxállítjuk össze. -
/ifcOutputbeállítja a megnevezett modul felületfájljának (.ifc) nevét. Például:/ifcOutput "somethingelse.ifc". Alapértelmezés szerint a fordító ugyanazt a nevet használja a modul felületfájlja (.ifc) számára, mint a modul forrásfájlja (.ixx) amelyet összeállít. A példában a létrehozottifcfájl alapértelmezés szerint azért vanstd.ifc, mert a modulfájltstd.ixxállítjuk össze.
-
Importálja a
stdlétrehozott tárat úgy, hogy először létrehoz egy fájltimportExample.cppa következő tartalommal:// requires /std:c++latest import std; int main() { std::cout << "Import the STL library for best performance\n"; std::vector<int> v{5, 5, 5}; for (const auto& e : v) { std::cout << e; } }Az előző kódban a
import std;helyettesíti a#include <vector>és#include <iostream>elemeket. Az utasításimport std;az összes standard kódtárat egyetlen utasítással teszi elérhetővé. A teljes standard kódtár importálása gyakran sokkal gyorsabb, mint egy szabványos kódtár fejlécfájljának feldolgozása, például#include <vector>.Fordítsa le a példát az előző lépéssel megegyező könyvtárban található alábbi paranccsal:
cl /c /std:c++latest /EHsc /nologo /W4 /reference "std=std.ifc" importExample.cpp link importExample.obj std.objEbben a példában nem szükséges a
/reference "std=std.ifc"megadása a parancssorban, mert a fordító automatikusan megkeresi azimportutasítás által megadott modulnevének megfelelő.ifcfájlt. Amikor a fordító találkozikimport std;, akkor megtalálhatjastd.ifc, ha ugyanabban a könyvtárban található, mint a forráskód. Ha a.ifcfájl a forráskódtól eltérő könyvtárban található, a/referencefordítókapcsolóval hivatkozhat rá.Ebben a példában a forráskód összeállítása és a modul implementációjának az alkalmazáshoz való csatolása külön lépések. Nem kell, hogy legyenek. Használhatja a
cl /std:c++latest /EHsc /nologo /W4 /reference "std=std.ifc" importExample.cpp std.obj-t arra, hogy egyetlen lépésben fordítson és linkeljen. Azonban célszerű lehet külön építeni és összekapcsolni, mert akkor csak egyszer kell létrehoznia a standard kódtár nevesített modult, majd a build hivatkozási lépésében hivatkozhat rá a projektből vagy több projektből.Ha egyetlen projektet hoz létre, a
stdstandard könyvtár modul létrehozásának lépéseit és az alkalmazás létrehozásának lépéseit kombinálhatja úgy, hogy hozzáadja a"%VCToolsInstallDir%\modules\std.ixx"a parancssorhoz. Helyezze a modult.cpphasználóstdfájlok elé.Alapértelmezés szerint a kimeneti végrehajtható fájl neve az első bemeneti fájlból származik. A fordítóprogram
/Feopciójával adja meg a kívánt végrehajtható fájlnevet. Ez az oktatóanyag bemutatja, hogyan állítsa össze külön lépésként astdnevű modult, mivel a standard könyvtár nevezetű modult csak egyszer kell létrehoznia, és aztán hivatkozhat rá a projektjéből vagy akár több projektből is. De kényelmes lehet mindent együtt felépíteni, ahogy az ebben a parancssorban látható:cl /FeimportExample /std:c++latest /EHsc /nologo /W4 "%VCToolsInstallDir%\modules\std.ixx" importExample.cppAz előző parancssor alapján a fordító létrehoz egy
importExample.exenevű végrehajtható fájlt. A futtatáskor a következő kimenet jön létre:Import the STL library for best performance 555
A standard kódtár és a globális C függvény importálása a következővel: std.compat
A C++ szabványkódtár tartalmazza az ISO C szabványkódtárat. A std.compat modul az összes funkcióját biztosítja, amit a std modul biztosít, például std::vector, std::cout, std::printf, std::scanf stb. De ezen függvények globális névtérverzióit is biztosítja, például ::printf, ::scanf, ::fopen, ::size_tstb.
A std.compat megnevezett modul egy kompatibilitási réteg, amely megkönnyíti a meglévő kód áttelepítését, amely a C futtatókörnyezeti függvényekre hivatkozik a globális névtérben. Ha el szeretné kerülni, hogy neveket adjon hozzá a globális névtérhez, használja a következőt import std;: . Ha egyszerűbben kell migrálnia egy olyan kódbázist, amely sok nem minősített (globális névtér) C futtatókörnyezeti függvényt használ, használja a következőt import std.compat;: . C-futtatókörnyezet globális névterében található nevek biztosításával nem szükséges az összes globális nevet std:: minősítéssel ellátnia. Ha nem rendelkezik olyan kóddal, amely a C futtatókörnyezet globális névterét használja, akkor nem kell használnia import std.compat;. Ha csak néhány C futtatókörnyezeti függvényt hív meg a kódban, akkor jobb lehet használni import std; és minősíteni azt a néhány globális névteret, amelynek C futtatókörnyezeti std::neve szükséges. Például: std::printf(). Ha a kód lefordításakor hasonló error C3861: 'printf': identifier not found hibaüzenet jelenik meg, fontolja meg a import std.compat; használatát a C futtató környezeti globális névtérfüggvények importálásához.
Példa: Felépítés és importálás std.compat
Mielőtt használhatná a import std.compat;, le kell fordítania a modul leírófájlját, amely forráskód formájában std.compat.ixx található. A Visual Studio a modul forráskódját tartalmazza, hogy a modult a projektnek megfelelő fordítóbeállítások használatával fordíthassa le. A lépések hasonlóak a std nevesített modul létrehozásához. A std nevesített modul azért van először felépítve, mert std.compat attól függ:
Nyisson meg egy Natív eszközök parancssort a VS-hez: a Windows Start menüjében írja be az x86 natív típust, és a parancssornak szerepelnie kell az alkalmazások listájában. Győződjön meg arról, hogy az előugró ablak a Visual Studio 2022 17.5-ös vagy újabb verziójára vonatkozik. Ha nem a megfelelő verziót használja, fordítási hibákat fog kapni.
Hozzon létre egy könyvtárat a példa kipróbálásához, például
%USERPROFILE%\source\repos\STLModulesaz aktuális könyvtárként. Ha olyan könyvtárat választ, amelyhez nem rendelkezik írási hozzáféréssel, hibaüzenetek jelennek meg.Fordítsa le a
stdésstd.compatelnevezett modulokat a következő paranccsal:cl /std:c++latest /EHsc /nologo /W4 /c "%VCToolsInstallDir%\modules\std.ixx" "%VCToolsInstallDir%\modules\std.compat.ixx"Az
stdésstd.compatkódokat ugyanazokkal a fordítóbeállításokkal kell komplikálnod, amelyeket majd az azokat importáló kód esetében is használni fogsz. Ha többprojektes megoldással rendelkezik, egyszer lefordíthatja őket, majd a fordítóval hivatkozhat rájuk az/referenceösszes projektből.Ha hibaüzenetet kap, győződjön meg arról, hogy a parancssor megfelelő verzióját használja.
A fordító négy fájlt ad ki az előző két lépésből:
-
std.ifcaz a megnevezett modulfelületként ismert lefordított bináris, amelyet a fordító aimport std;utasítás feldolgozásához használ. A fordító astd.ifcis konzultáljaimport std.compat;feldolgozása érdekében, mertstd.compatazstd-re épít. Ez egy kizárólag fordítási időben létező összetevő. Nem szállítják az alkalmazással együtt. -
std.objA standard kódtár implementációját tartalmazza. -
std.compat.ifca lefordított bináris modul interfész neve, amelyet a fordító aimport std.compat;utasítás feldolgozásához kér le. Ez csak fordítási idejű összetevő. Nem része az alkalmazás csomagjának. -
std.compat.objimplementációt tartalmaz. A megvalósítás nagy részét azonban astd.objbiztosítja. Amikor a mintaalkalmazást fordítja, adja hozzá astd.obj-t a parancssorhoz, hogy a standard kódtárból az alkalmazáshoz használt funkciókat statikusan csatolja.
Az objektumfájl nevét és a modul felületének nevét a következő kapcsolókkal szabályozhatja:
-
/Foaz objektumfájl nevét állítja be. Például:/Fo:"somethingelse". Alapértelmezés szerint a fordító ugyanazt a nevet használja az objektumfájlhoz, mint a modul forrásfájlja (.ixx) amelyet összeállít. A példában alapértelmezés szerintstd.objésstd.compat.objaz objektumfájlnevek, mert a modulfájlokatstd.ixxésstd.compat.ixxállítjuk össze. -
/ifcOutputbeállítja a megnevezett modul felületfájljának (.ifc) nevét. Például:/ifcOutput "somethingelse.ifc". Alapértelmezés szerint a fordító ugyanazt a nevet használja a modul felületfájlja (.ifc) számára, mint a modul forrásfájlja (.ixx) amelyet összeállít. A példában a létrehozottifcfájlok alapértelmezés szerintstd.ifcésstd.compat.ifcfájlok, mert astd.ixxésstd.compat.ixxmodulfájlokat fordítjuk.
-
Importálja a
std.compattárat úgy, hogy először létrehoz egy fájltstdCompatExample.cppa következő tartalommal:import std.compat; int main() { printf("Import std.compat to get global names like printf()\n"); std::vector<int> v{5, 5, 5}; for (const auto& e : v) { printf("%i", e); } }Az előző kódban a
import std.compat;helyettesíti a#include <cstdio>és#include <vector>elemeket. Az utasításimport std.compat;egy utasítással elérhetővé teszi a standard kódtárat és a C futtatókörnyezeti függvényeket. Ennek a nevesített modulnak az importálása, amely magában foglalja a C++ standard könyvtárat és a C futtatókörnyezeti könyvtár globális névtér függvényeit, gyorsabb, mint feldolgozni egyetlen#includehasonló#include <vector>.A példa lefordítása a következő parancs használatával:
cl /std:c++latest /EHsc /nologo /W4 stdCompatExample.cpp link stdCompatExample.obj std.obj std.compat.objNem kellett megadni
std.compat.ifca parancssorban, mert a fordító automatikusan megkeresi azt a fájlt, amely megfelel a.ifcmodul nevének egyimportutasításban. Amikor a fordító találkozikimport std.compat;-val, észleli astd.compat.ifc-t, mivel ugyanabba a könyvtárba helyeztük, mint a forráskódot, így nem szükséges megadni a parancssorban. Ha a.ifcfájl más könyvtárban található, mint a forráskód, vagy más néven van, a/referencefordító kapcsolóval hivatkozhat rá.Importáláskor össze kell kapcsolni mind
std.compat, mindstd.objelemmel, mertstd.compatkódot használstd.obj-ban.Ha egyetlen projektet hoz létre, kombinálhatja a
stdés astd.compatstandard könyvtárat elnevezett modulok létrehozásának lépéseit azáltal, hogy a"%VCToolsInstallDir%\modules\std.ixx"és"%VCToolsInstallDir%\modules\std.compat.ixx"(ebben a sorrendben) hozzáadja a parancsorhoz. Ez az oktatóanyag azt mutatja be, hogy a standard kódtármodulokat külön lépésként kell felépíteni, mert csak egyszer kell létrehoznia a standard kódtár nevesített moduljait, majd a projektből vagy több projektből is hivatkozhat rájuk. Ha azonban kényelmes egyszerre felépíteni őket, ügyeljen arra, hogy azokat minden olyan fájl elé.cpphelyezze, amely felhasználja őket, és adja meg/Fe, hogy a buildetexeaz alábbi példában látható módon nevezze el:cl /c /FestdCompatExample /std:c++latest /EHsc /nologo /W4 "%VCToolsInstallDir%\modules\std.ixx" "%VCToolsInstallDir%\modules\std.compat.ixx" stdCompatExample.cpp link stdCompatExample.obj std.obj std.compat.objEbben a példában a forráskód összeállítása és a modul implementációjának az alkalmazáshoz való csatolása külön lépések. Nem kell, hogy legyenek. Használhatja a
cl /std:c++latest /EHsc /nologo /W4 stdCompatExample.cpp std.obj std.compat.obj-t arra, hogy egyetlen lépésben fordítson és linkeljen. Célszerű lehet azonban külön építeni és összekapcsolni a modulokat, mert akkor csak egyszer kell létrehoznia a standard kódtár nevesített moduljait, majd a build hivatkozási lépésében hivatkozhat rájuk a projektből vagy több projektből.Az előző fordítóparancs létrehoz egy végrehajtható nevet
stdCompatExample.exe. A futtatáskor a következő kimenet jön létre:Import std.compat to get global names like printf() 555
Standard kódtár nevesített modulokkal kapcsolatos szempontok
A megnevezett modulok verziószámozása megegyezik a fejlécek verziószámozásával. A .ixx nevesített modulfájlok a fejlécek mellett vannak telepítve, például: "%VCToolsInstallDir%\modules\std.ixx", amely az íráskor használt eszközök verziójában oldható fel C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.38.33130\modules\std.ixx . Válassza ki az elnevezett modul verzióját ugyanúgy, ahogyan a használni kívánt fejlécfájl verzióját – a hivatkozott könyvtár alapján.
Ne keverje a fejlécegységek importálását és a megnevezett modulokat. Például ne import <vector>; és import std; ugyanabban a fájlban.
Ne keverje és ne használja vegyesen a C++ szabványkönyvtár fejlécfájljait és a megnevezett modulokat std vagy std.compat. Például ne #include <vector> és import std; ugyanabban a fájlban. A C fejléceket azonban belefoglalhatja, és importálhatja a nevesített modulokat ugyanabban a fájlban. Például ugyanabban a fájlban [művelet1] és [művelet2] is elvégezhető. Csak ne tartalmazza a C++ standard kódtár verzióját <cmath>.
Nem kell többször védekeznie egy modul importálása ellen. Vagyis nincs szükség stílusfejléc-védőkre #ifndef a modulokban. A fordító tudja, hogy mikor importált már egy elnevezett modult, és figyelmen kívül hagyja az ismétlődő próbálkozásokat.
Ha a makrót assert() kell használnia, akkor #include <assert.h>.
Ha a makrót errno kell használnia, #include <errno.h>. Mivel a nevesített modulok nem teszik elérhetővé a makrókat, például az <math.h> hibák keresésére, ez a megoldás.
Az olyan makrókat, mint a NAN, INFINITY és INT_MIN, a <limits.h> határozza meg, amelyeket belefoglalhat. Azonban, ha import std;, akkor használhatja std::numeric_limits<double>::quiet_NaN() és std::numeric_limits<double>::infinity()-t a NAN és INFINITY helyett, valamint std::numeric_limits<int>::min()-t a INT_MIN helyett.
Összefoglalás
Ebben az oktatóanyagban modulokkal importálta a standard kódtárat. A következő lépésben megismerheti saját moduljainak létrehozását és importálását a Nevesített modulok oktatóanyagban a C++-ban.
Lásd még
Fejlécegységek, modulok és előre összeállított fejlécek összehasonlítása
A C++ moduljainak áttekintése
C++ modulok bemutatója a Visual Studióban
Projekt áthelyezése C++ nevű modulokba