C++23: Modülerleştirilmiş bir standart kitaplık ve iki yeni işlev
C++23 Standart Kitaplığı etkileyici iyileştirmelerle parlıyor. Bu yazımda modülerleştirilmiş standart kütüphaneden ve iki kullanışlı özelliğinden bahsedeceğim. std:rint VE std:rintln yazmak.
Duyuru
Rainer Grimm uzun yıllardır yazılım mimarı, ekip lideri ve eğitim yöneticisi olarak çalışmaktadır. C++, Python ve Haskell programlama dilleri üzerine makaleler yazmayı seviyor ama aynı zamanda özel konferanslarda sık sık konuşmayı da seviyor. Modernes C++ adlı blogunda yoğun bir şekilde C++ tutkusundan bahsediyor.
Yeni bir dilde her kodlama mücadelesi “Merhaba Dünya” programıyla başlar. C++98’den bu yana başlangıç noktamız şu oldu:
#include <iostream>
int main() {
std::cout << "Hello Worldn";
}
Açıkçası eski C++23 alışkanlıklarınızdan vazgeçmeniz gerekiyor. “Merhaba Dünya” programı artık şöyle görünüyor:
import std;
int main() {
std:rintln("Hello World");
}
Programı analiz edelim.
Duyuru
Modülerleştirilmiş standart kütüphane
C++23 modülerleştirilmiş bir standart kitaplığı destekler. Basit komutla import std; standart kütüphanenin tamamı hizmetinizdedir. Eğer global C fonksiyonlarını da seviyorsanız printf onu kullanmalısın import std.compat; kullanım. İşte ilgili “Merhaba Dünya” programı printf:
import std.compat;
int main() {
printf("Hello Worldn");
}
Modülerleştirilmiş standart kitaplık iki önemli iyileştirme sağlar: büyük ölçüde geliştirilmiş oluşturma süresi ve kullanılabilirlik.
Büyük ölçüde geliştirilmiş derleme süresi
Standart kütüphanenin içe aktarılması (import std) kelimenin tam anlamıyla “ücretsizdir”. Bu, yapım sürelerinin önemli ölçüde azaldığı anlamına gelir. Deneyimlerden elde edilen ilk veriler, derleme sürelerinin en az 10 kat kısaldığını gösteriyor. Bu iyileşmenin nedeni açıktır. Başlık dosyalarını daha sonra eklemek yerine bir modülü içe aktarırsınız. Bu nedenle C++23 standart kütüphanesinin tamamını içeren tek bir modül vardır. Şu ana kadar yalnızca MSVC derleyicisi bu modülerleştirilmiş standart kitaplığı desteklemektedir: Öğretici: Komut satırından modülleri kullanarak C++ Standart Kitaplığını içe aktarın.
Geliştirilmiş kullanılabilirlik
Diyelim ki fonksiyonu istiyorsunuz std::accumulate kullanım. Hangi başlık dosyasını dahil edeceğinizi biliyor musunuz? Bu başlık dosyasınumeric>,functional> veyaalgorithm>? Belki senin için çok kolaydı. Şimdiki gibi? std::forward veya aşağıdaki programı neden derleyemiyorsunuz?
int main() {
auto list = {1, 2, 3, 4};
}
İfade {1, 2, 3, 4} bu bir std::initializer_list<int>. Bunları kullanmak için başlıkinitializer_list> kullanılır. Doğal olarak bir kapsayıcı beğenildiğinde bu başlık otomatik olarak dahil edilir std::vector kullanılmış.
Önceki örnekleri basit bir örnekle karşılaştırın import std; VEYA import std::compat;. Kişisel deneyimimden biliyorum: Doğru başlık dosyalarını kullanırken yalnızca yeni başlayanlar sıklıkla başarısız olmaz.
Bunu fark ettiniz mi bilmiyorum ama C++23 “Merhaba Dünya” programım C++23’ün ikinci bir özelliğini kullanıyordu:
std:rint VE std:rintln
C++23 her iki işlev için de iki aşırı yükleme sunar:
std:rint
template< class... Args >
void print( std::FILE* stream,
std::format_string<Args...> fmt, Args&&... args );
template< class... Args >
void print( std::format_string<Args...> fmt, Args&&... args );
std:rintln
template< class... Args >
void println( std::FILE* stream,
std::format_string<Args...> fmt, Args&&... args );
template< class... Args >
void println( std::format_string<Args...> fmt, Args&&... args );
Aradaki ilk fark std:rint VE std:rintln çok açık: std:rintln satır sonu ekler. Aşağıdaki noktalar daha da ilginç:
Variadik model
std:rint VE std:rintln bunlar değişken modellerdir. Değişken modeller herhangi bir sayıda argüman alabilen modellerdir. Argümanlarınız mükemmel bir şekilde aktarılıyor. std:rint VE std:rintln türü açısından güvenli olan çeşididir printf. İLE printf biçim dizesini şu adreste belirtmeniz gerekir: std:rint VE std:rintln biçim dizesinde joker karakterler kullanırsınız. Genel olarak derleyici, yer tutucular için veri türünü aşağıdaki kurallara uyarak çıkarır: std::format C++20’den itibaren geçerlidir. mantıklı görünüyor std:rint VE std:rintln C++20’deki biçim dizeleri için C++23 sözdizimsel şekerinde olun. İşte C++23’te değiştirilmiş “Merhaba Dünya” programı std::format kullanılmış.
import std;
int main() {
// std:rintln("Hello World");
std::cout << std::format("{:}n", "Hello World");
}
Variadic, Perfect Forwarding ve hakkında daha fazla bilgi edinmek istiyorsanız std::formaBilmek istemiyorsanız eski yazılarımı okuyun:
Unicode desteği
O std:rint VE std:rintln C++23’te C++20’deki biçim dizeleri için Sözdizimsel Şeker doğru değil. Neden std:rint VE std:rintln Unicode’u destekleyin. Size P2093R14 teklifinden alıntı yapayım:
Başka bir sorun da Unicode metin biçimlendirmesidir:
std::cout << "Привет, κόσμος!";
Kaynak ve yürütme kodlaması UTF-8 ise bu, çoğu GNU/Linux ve macOS sisteminde beklenen çıktıyı üretecektir. Ne yazık ki Windows’ta, sistemin tam olarak Unicode yazdırma kapasitesine sahip olmasına rağmen mojibakes üretmesi neredeyse garantidir, örneğin
Привет κόσμος!
Visual C++ kullanılarak /utf-8 ile derlendiğinde bile ([MSVC-UTF8]). Bunun nedeni, bu durumda terminalin, yürütme kodlamasından bağımsız olarak kod sayfası 437’yi üstlenmesidir.
Önerilen belgeyle
std:rint("Привет, κόσμος!");
“Привет, κόσμος!” yazdırmak istiyor amaçlandığı gibi, programcıların standart özellikleri kullanarak Unicode metni taşınabilir bir şekilde yazmasına olanak tanır.
Herhangi bir çıktı akışı
Her iki tür std:rint VE stdrintln herhangi bir çıkış akışını kabul eden bir aşırı yüke sahip olun. Varsayılan olarak çıkış akışıdır stdout.
std::format ve dolayısıyla da std:rint VE std:rintln C++23’te daha da fazlasını sunabilirsiniz. C++23’te standart bir şablon kitaplığı kapsayıcısını biçimlendirebilirsiniz.
Bir kabın biçimlendirilmiş çıktısı
Aşağıdaki program, STL’nin bir konteynerinin doğrudan nasıl çıkarılabileceğini gösterir. Şu ana kadar hiçbir C++ derleyicisi bu özelliği desteklememektedir. Yalnızca uzantıya sahip yepyeni Clang derleyicisi libc++ yerine libstdc++ bu fonksiyonun en azından kısmen kullanılmasını mümkün kılar. Tamamen uyumlu bir C++23 uygulamasında, std:rintln yerine std::format kullanım.
// formatVector.cpp
#include <format>
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<int> myInts{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << std::format("{:}n", myInts);
std::cout << std::format("{::+}n", myInts);
std::cout << std::format("{::02x}n", myInts);
std::cout << std::format("{::b}n", myInts);
std::cout << 'n';
std::vector<std::string> myStrings{"Only", "for", "testing", "purpose"};
std::cout << std::format("{:}n", myStrings);
std::cout << std::format("{::.3}n", myStrings);
}
Bu örnekte birini kullanıyorum std::vector<int> biridir std::vector<std::string>. öz {:} yer tutucu olarak kullanıldığında, her iki kapsayıcı da (satır 1 ve 2) doğrudan görüntülenir. İki iki nokta üst üste olur {::} yer tutucu içinde kullanılan öğelerin std::vector biçim. Biçim belirtici ikinci iki nokta üst üste işaretinden sonra gelir.
- std::vector<int>: Vektör öğelerinde + işareti bulunur {::+}dolgu karakteri 0 olan 2 karakterden oluşan onaltılıktır {::02x} hizalanır ve ikili olarak temsil edilir {::b}.
- std::vector<std::string>: Her dize ilk 3 karaktere kadar kesilir: {::.3}.
Sıradaki ne?
C++23’te geliştirilmiş standart kütüphane ile ilgili bir sonraki yazımda genişletilmiş arayüzünü kullanacağım. std:ptional ve yeni veri türü std::expected Hata yönetimi için mevcut.
(harita)
Haberin Sonu