Zatwierdzono standard C++26

Komitet ISO ds. standaryzacji języka C++ zakończył zatwierdzanie ostatecznej wersji specyfikacji, która stanowi międzynarodowy standard „C++26”. Funkcjonalności zawarte w specyfikacji są częściowo już wspierane przez kompilatory GCC, Clang i Microsoft Visual C++. Standardowe biblioteki obsługujące C++26 zostały zaimplementowane w ramach projektu Boost.

W ciągu najbliższych dwóch miesięcy zatwierdzona specyfikacja będzie poddawana opracowaniu dokumentu do publikacji, podczas którego przeprowadzona zostanie redakcyjna korekta błędów ortograficznych i literówek. Na początku listopada ostateczna wersja dokumentu zostanie przesłana do ISO w celu publikacji pod formalną nazwą ISO/IEC 14882:2026.

Główne cechy C++26:

  • Zrealizowane elementy programowania kontraktowego (Contracts), które pozwalają na definiowanie formalnych specyfikacji interfejsów za pomocą trzech nowych operatorów: pre (warunek wstępny), post (warunek końcowy) i contract_assert (sprawdzanie założeń). Operator „pre” definiuje warunki wstępne, które muszą być spełnione przed wywołaniem (weryfikacja danych wejściowych); „post” — warunki, które muszą być przestrzegane po wykonaniu (wymagania dotyczące danych wyjściowych); contract_assert — warunki dotyczące występowania wyjątków. Możliwość ta pojawi się w GCC 16. int f(const int x) pre (x != 1) // wymagania dotyczące danych wejściowych post (r : r == x && r != 2) // wymagania dotyczące wyniku; r — wartość rezultatu { contract_assert (x != 3); return x; }
  • Dodano wsparcie dla refleksji (Reflection), umożliwiające śledzenie i modyfikowanie elementów programu na etapie kompilacji. Dodano nowe operatory „^^” do uzyskiwania informacji meta o konstrukcjach gramatycznych oraz „[:…:]” do wykonywania odwrotnej konwersji. Do konwersji i przetwarzania informacji uzyskanej podczas inspekcji zaproponowano bibliotekę std::meta, a dostępne możliwości obejmują obliczenia z użyciem stałych. Wsparcie dla refleksji będzie dodane w GCC 16. constexpr int i = 42, j = 42; constexpr std::meta::info r = ^^i, s = ^^i; static_assert(r == r && r == s); static_assert(^^i != ^^j); // ‘i’ i ‘j’ mają różne wartości. static_assert(constant_of(^^i) == constant_of(^^j)); // ‘i’ i ‘j’ są takie same static_assert(^^i != std::meta::reflect_constant(42)); // różni się od wartości 42
  • Dodano operator „template for” do iteracji po elementach, takich jak pakiety parametryczne, obiekty podobne do krotek i wyniki refleksji (metaobiekty), na etapie kompilacji w stylu tradycyjnej pętli. Podczas wykonania „template for” ciało pętli jest rozwijane dla każdego elementu, a każda iteracja jest przetwarzana w oddzielnym zasięgu, w którym zmienna zmieniająca się w pętli jest stałą. W kontekście refleksji „template for” może być używane do przechodzenia po właściwościach klas lub enumeracji. Możliwość ta pojawi się w GCC 16. void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } } zostanie rozwinięta do: void f() { { constexpr auto&& __range = std::array{1, 2, 3}; constexpr auto __begin = __range.begin(); constexpr auto __expansion-size = __range.end() - __begin; // 3 { constexpr int I = *(__begin + 0); static_assert(I < 4); } { constexpr int I = *(__begin + 1); static_assert(I < 4); } { constexpr int I = *(__begin + 2); static_assert(I < 4); } } }
  • Dodano framework std::execution do asynchronicznego i równoległego wykonywania kodu. Udostępnione są obiekty scheduler, definiujące planistę wykonania zadań (wątek, pula wątków, GPU, pętla zdarzeń), sender, definiujący wykonaną pracę, i receiver —处理器结果. using namespace std::execution; scheduler auto sch = thread_pool.scheduler(); sender auto begin = schedule(sch); sender auto hi = then(begin, []{ std::cout < "Hello world! Have an int."; return 13; }); sender auto add_42 = then(hi, [](int arg) { return arg + 42; }); auto [i] = this_thread::sync_wait(add_42).value();
  • Dodano bibliotekę std::simd do równoległego wykonywania operacji na danych za pomocą zestawów instrukcji SIMD, takich jak AVX-512 i NEON, z wykorzystaniem standardowego systemu typów C++. std::simd a = {1.0f, 2.0f, 3.0f, 4.0f}; std::simd b = {5.0f, 6.0f, 7.0f, 8.0f}; std::simd result = a + b;
  • Zaprezentowano implementację wektora (tablicy) zmiennej wielkości std::inplace_vector, umieszczanego na stosie, którego rozmiar jest określany na etapie kompilacji. API jest zbliżone do std::vector, ale elementy tablicy są przechowywane nie w „kupie”, lecz w obrębie obiektu. inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
  • Dodano dyrektywę „#embed”, przeznaczoną do wbudowywania w kod binarnych zasobów. const unsigned char icon_display_data[] = { #embed "art.png" };
  • Dodano wsparcie dla generowania i obsługi wyjątków na etapie kompilacji w przypadku błędów w kontekście constexpr. constexpr std::optional checked_divide(unsigned n, unsigned d) { try { return divide(n, d); } catch (…) { return std::nullopt; } } constexpr date parse_date(std::string_view input) { auto [correct, year, month, day] = ctre::match(input); if (!correct) { throw incorrect_date{input}; } return build_date(year, month, day); }
  • Zaimplementowano strukturę danych std::hive do nieuporządkowanego przechowywania danych oraz umożliwienia ponownego wykorzystania pamięci zwolnionej po usuniętych elementach. Struktura jest zoptymalizowana do obciążeń o wysokiej intensywności dodawania i usuwania elementów w dowolnej kolejności. W przeciwieństwie do tablic, usunięcie elementu w std::hive nie powoduje przemieszczenia innych elementów, a tylko oznaczenie usuniętego elementu jako pustego, z późniejszym wypełnieniem zwolnionej pozycji podczas dodawania nowego elementu.
  • Dodano bibliotekę std::linalg z API do algebry liniowej, opartej na BLAS.
  • Dodano wsparcie dla mechanizmu synchronizacji Hazard pointer, który pozwala na zapobieganie zwalnianiu pamięci obiektów, z którymi nadal pracują inne wątki, bez stosowania blokad. Podczas usuwania obiektu jest on tylko oznaczany jako usunięty, a pamięć zajmowana przez obiekt jest zwalniana dopiero, gdy wszystkie wątki usuną hazard wskaźnik ustawiany podczas pracy z obiektem.
  • Dodano wsparcie dla mechanizmu synchronizacji RCU (Read-Copy Update) — podczas operacji zapisu tworzony jest nowy egzemplarz obiektu, a operacje odczytu nie są blokowane, lecz kontynuują pracę ze starym egzemplarzem. Po zakończeniu zmiany nowy egzemplarz staje się aktywny, a nowe operacje odczytu są już przeprowadzane z nim, podczas gdy stary egzemplarz jest usuwany po zakończeniu odczytów przez wątki, które go używały.
  • Wprowadzono zmiany mające na celu zwiększenie bezpieczeństwa standardowej biblioteki, takie jak kontrole wartości dopuszczalnych oraz wychodzenia poza granice bufora. Na przykład, przy dostępie do elementu „constexpr reference operator[](size_type idx) const;” dodawana jest kontrola warunku „idx < size()".
  • Udostępniono możliwość użycia słowa kluczowego „constexpr” z odmianą operatora „new” (placement new) do umieszczania obiektu w uprzednio przydzielonej pamięci podczas kompilacji.
  • Dodano wsparcie dla powiązań strukturalnych (structured binding) w kontekście 'constexpr', tzn. odwołania do stałych wyrażeń mogą same być stałymi wyrażeniami. Wsparcie zostało zrealizowane dla tablic i prostych struktur. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
  • W powiązania strukturalne dodano możliwość użycia składni '...' do wskazywania pakietów (pack), które przechwytują pozostałą liczbę elementów z przypisywanej sekwencji. auto [x,y,z] = f(); // do zmiennych x, y, z zostaną zapisane trzy elementy zwrócone przez f(). auto […xs] = f(); // do pakietu xs zostaną zapisane wszystkie elementy zwrócone przez f(). auto [x, …rest] = f(); // W x zostanie zapisany pierwszy element, a w rest — pozostałe. auto [x, y, …rest] = f(); // W x zostanie zapisany pierwszy element, w y — drugi, a w rest — trzeci. auto [x, …rest, z] = f(); // w x — pierwszy, w rest — drugi, w z — trzeci.
  • Dodano wsparcie dla 'trivialnej przenośności' typów (Trivial Relocatability), co pozwala na optymalizację przenoszenia obiektów danego typu przez ich klonowanie w pamięci bez wywoływania konstruktorów lub destruktorów. Dla klas wprowadzono właściwości memberwise_trivially_relocatable i memberwise_replaceable, a dla niskopoziomowego przenoszenia jednego lub kilku obiektów dodano funkcje trivially_relocate_at i trivially_relocate.
  • Wprowadzono wsparcie dla przypisywania funkcji main() do globalnego modułu oraz definiowania funkcji main() w nazwanych modułach.
  • Dodano wariantowy operator 'friend' ('friend Ts...').
  • Zrealizowano atrybuty dla powiązań strukturalnych.
  • Dodano składnię '= delete("powód")'.
  • Do podstawowego zestawu symboli dodano '@', '$' i '`'.
  • Umożliwiono zastosowanie powiązania strukturalnego (structured binding) jako warunku w operatorach if i switch.
  • Dodano możliwość użycia wielu zmiennych-wypełniaczy o nazwie '_' w jednej przestrzeni nazw, na przykład, teraz poprawne są konstrukcje: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // wcześniej wyświetlano ostrzeżenie w trybie -Wunused }
  • Wprowadzono możliwość używania literałów ciągów w kontekście, w którym nie są one używane do inicjalizacji tablicy znaków i nie trafiają do wynikowego kodu, a stosowane są tylko podczas kompilacji do komunikatów diagnostycznych i preprocessingu, na przykład jako parametry dyrektyw i atrybutów _Pragma, asm, extern, static_assert, [[deprecated]] i [[nodiscard]].
  • Dodano wbudowane funkcje: „__builtin_is_within_lifetime” do sprawdzania aktywności alternatywy w uniach (union) oraz „__builtin_is_virtual_base_of” do sprawdzania, czy klasa bazowa jest wirtualna.
  • Zrealizowano trywialne nieskończone pętle bez nieokreślonego zachowania.
  • Zapewniono wyświetlanie błędu przy usuwaniu wskaźnika na typ niepełny.
  • Została uznana za przestarzałą składnia definiowania parametrów wariancyjnych z wielokropkiem bez poprzedzającego przecinka (na przykład, gdy określono „void e(int…)” zamiast „void e(int, …)”).
  • Zabroniono używania makr do deklarowania modułów.
  • Przeklasyfikowano na przestarzałe wykonywanie niejawnych konwersji wartości wyliczonych w obliczeniach arytmetycznych. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // przestarzałe int k = f - e; // przestarzałe int x = +f - e; // OK }
  • Zakończono wsparcie dla bezpośredniego porównywania tablic. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
  • Została uznana za przestarzałą szablonowa klasa is_trivial.

    Źródło: opennet.ru
Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster