C++23: Modülerleştirilmiş bir standart kitaplık ve iki yeni işlev

Adanali

Active member
C++23: Modülerleştirilmiş bir standart kitaplık ve iki yeni işlev


  1. 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::print VE std::println 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::println("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::print VE std::println


C++23 her iki işlev için de iki aşırı yükleme sunar:

std::print


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::println


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::print VE std::println çok açık: std::println satır sonu ekler. Aşağıdaki noktalar daha da ilginç:

Variadik model


std::print VE std::println 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::print VE std::println türü açısından güvenli olan çeşididir printf. İLE printf biçim dizesini şu adreste belirtmeniz gerekir: std::print VE std::println 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::print VE std::println 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::println("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::print VE std::println C++23’te C++20’deki biçim dizeleri için Sözdizimsel Şeker doğru değil. Neden std::print VE std::println 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::print("Привет, κόσμος!");

“Привет, κόσμος!” 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::print VE std:println 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::print VE std::println 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::println 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}.
Aşağıdaki ekran görüntüsü programın Derleyici Gezgini’ndeki çıktısını gösterir:








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::eek:ptional ve yeni veri türü std::expected Hata yönetimi için mevcut.


(harita)



Haberin Sonu
 
Üst