C ++ 26'ya genel bir bakış: Çekirdek dil

Adanali

Active member
C ++ 26'ya genel bir bakış: Çekirdek dil


  1. C ++ 26'ya genel bir bakış: Çekirdek dil

Bu görüntü, C ++ 26'nın nasıl oluşturulduğuna dair bir ilk izlenim sunar.

















Rainer Grimm yıllardır yazılım mimarı, ekip ve eğitim müdürü olarak çalıştı. C ++ programlama dilleri, Python ve Haskell hakkında makaleler yazmayı seviyor, ancak uzman konferanslarla konuşmayı da seviyor. Modern C ++ blogunda, C ++ tutkusuyla yoğun bir şekilde ilgileniyor.







Bulutlu sularda balıkçılık


Görüntü sadece C ++ 26'nın nasıl göründüğüne dair ilk izlenim vermelidir. Önümüzdeki aylarda C ++ 26 hakkında yazıyorum, gerekirse uyarlayacağım. Örneğin, üç güçlü özellik yansıttı, sözleşmeler ve std::execution Standardizasyonlarına doğru büyük bir adım attı. Aksine, fotoğraftaki nedenin yazışmasını kasten görmezden geliyorum.

Yansıma veya sözleşmeler gibi çok etkili özellikler, uygulanabilir minimum ürünün çevik fikrini uygular:

“Minimum uygulanabilir ürün (MVP), bu nedenle ürünün gelecekteki gelişimi için geri bildirim sağlayabilen ilk müşteriler tarafından kullanılacak kadar işlevselliğe sahip bir ürünün versiyonudur.”

Bu, C ++ 26'nın yalnızca yansıma veya sözleşmeler gibi işlevsellik için başlangıç noktası olduğu anlamına gelir. Mümkünse, eylemdeki özellikleri gösteririm. Yepyeni C ++ derleyicilerinde birçok özellik zaten uygulanmıştır. Geri kalanı için prototip uygulamaları umuyorum.

Ana dille başlıyorum.

Ana dil


Refleks

Yansıma, bir programın yapısını ve davranışını inceleme, düşünme ve değiştirme yeteneğidir. Bu, C ++ 'daki derleme süresi programlamasını çok daha güçlü hale getirir. Bu makalede çok fazla teori ile sıkılmak istemiyorum. Bu yüzden size en sevdiğim örneği P2996R5 yansıma teklifinden gösteriyorum.

Kurslarımda sık sık cevaplamam gereken bir soru okuyor: Bir numaralandırıcıyı bir dizeye nasıl dönüştürebilirim?


// enumString.cpp

#include <iostream>&#13;
#include <experimental/meta>&#13;
#include <string>&#13;
#include <type_traits>&#13;
&#13;
// start 'expand' definition&#13;
namespace __impl {&#13;
template<auto... vals>&#13;
struct replicator_type {&#13;
template<typename F>&#13;
constexpr void operator>>(F body) const {&#13;
(body.template operator()<vals>(), ...);&#13;
}&#13;
};&#13;
&#13;
template<auto... vals>&#13;
replicator_type<vals...> replicator = {};&#13;
}&#13;
&#13;
template<typename R>&#13;
consteval auto expand(R range) {&#13;
std::vector<std::meta::info> args;&#13;
for (auto r : range) {&#13;
args.push_back(std::meta::reflect_value(r));&#13;
}&#13;
return substitute(^__impl::replicator, args);&#13;
}&#13;
// end 'expand' definition&#13;
&#13;
template<typename E>&#13;
requires std::is_enum_v<E> // (1)&#13;
constexpr std::string enum_to_string(E value) {&#13;
std::string result = "<unnamed>";&#13;
[:expand(std::meta::enumerators_of(^E)):] >> // (2)&#13;
[&]<auto e>{&#13;
if (value == [:e:]) {&#13;
result = std::meta::identifier_of(e); // (3)&#13;
}&#13;
};&#13;
return result;&#13;
}&#13;
&#13;
&#13;
int main() {&#13;
&#13;
std::cout << 'n';&#13;
&#13;
enum Color { red, green, blue };&#13;
std::cout << "enum_to_string(Color::red): " << enum_to_string(Color::red) << 'n';&#13;
// std::cout << "enum_to_string(Color(42)): " << enum_to_string(42) << 'n'; &#13;
&#13;
std::cout << 'n';&#13;
&#13;
}


Bu örnekte, deneysel özellikler (std::meta)). İşte programın baskısı:








İşlevsel modelde kısaca istiyorum enum_to_string girmek. İşlev expand Bu sadece alternatif bir çözüm. Denilen işlev enum_to_string(Color(42)) Durur çünkü işlev bir numaralandırma gerektirir: requires std::is_enum_v<E> (Satır 1).

Hat (1) bir yansıma operatörünü dönüştürür (^E) ve meta işlevini arayın enum_to_std::meta::enumerators_of(^E) AÇIK. Sonunda, sözde Spicer ([:refl:]))) (2) yansıma için dilbilgisi unsurları. (3) satır (3) 'deki ikinci hedef -dizeyi oluşturun: std:meta::identifier_of(e)). Meta fonksiyonlar derleme dönemine ve yansıma için gerçekleştirilir.

Sözleşmeler

Bir sözleşme, yazılım bileşenleri için arayüzleri belirler ve kontrol eder. Yazılımın bu bileşenleri, önceden sözleşmeler, direkler ve değişmez olan işlevlerdir.

İşte P2900 teklifinin basit bir örneği.


int f(const int x)&#13;
pre (x != 1) // a precondition assertion&#13;
post(r : r != 2) // a postcondition assertion; r refers to the return value of f&#13;
{&#13;
contract_assert (x != 3); // an assertion statement&#13;
return x;&#13;
}


İşlev f Bir ön koşul, takip ve değişmez. Önkoşul, fonksiyonel çağrıdan önce, işlevin çağrısından sonra arka koşul ve çağrı sırasında değişmezden önce kontrol edilir.

İşlevi 1, 2 veya 3 konularıyla arayın, sözleşmenin ihlaline yol açar. Sözleşmenin ihlaline tepki vermenin çeşitli yolları vardır.


void g()&#13;
{&#13;
f(0); // no contract violation&#13;
f(1); // violates precondition assertion of f&#13;
f(2); // violates postcondition assertion of f&#13;
f(3); // violates assertion statement within f&#13;
f(4); // no contract violation&#13;
}


Yansıma ve sözleşmelere ek olarak, C ++ 26'nın temel dili daha da fazla sunmaktadır. Onları kısaca vermek ve ilgili önerilerden bir kod bölümünü sunmak istiyorum.

  • Karakterler ve geniş karakterler

auto [x, y, _] = f();


Altı çizili (_) “Umurumda değil” için. Ve birkaç kez kullanılabilir.

  • static_assertGenleşme

static_assert(sizeof(S) == 1,&#13;
std::format("Unexpected sizeof: expected 1, got {}", sizeof(S))


C ++ 26'daki modellerde birçok gelişme var. Benim favorim paketin göstergesidir:


template <typename... T>&#13;
constexpr auto first_plus_last(T... values) -> T...[0] {&#13;
return T...[0](values...[0] + values...[sizeof...(values)-1]);&#13;
}&#13;
&#13;
int main() {&#13;
//first_plus_last(); // ill formed&#13;
static_assert(first_plus_last(1, 2, 10) == 11);&#13;
}


delete("Should have a reason");


Sırada ne var?


Bir sonraki makalemde C ++ 26 kitapçığına genel bir bakış vereceğim.


(Mayıs)
 
Üst