C ++ 26'da yansıma: Veri türlerinin düzenini belirleyin

Adanali

Active member
C ++ 26'da yansıma: Veri türlerinin düzenini belirleyin


  1. C ++ 26'da yansıma: Veri türlerinin düzenini belirleyin

C ++ 26'da yansıma girişinden sonra, meta fonksiyonların temel bir tanıtımı ve enum ve sınıflara genel bir bakış, bu sefer veri türlerinin düzenini belirlemek için yansıma nasıl kullanılabileceğidir.













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.







Örneklerim P2996R5 yansıma teklifine dayanmaktadır.

Sınıf düzeninin görünümü


Aşağıdaki program bazı üyelerin sınıf düzenini belirler.


// classLayout.cpp

#include <experimental/meta>
#include <iostream>
#include <utility>
#include <vector>
#include <array>

struct member_descriptor
{
std::size_t offset;
std::size_t size;
bool operator==(member_descriptor const&) const = default;
};

// returns std::array<member_descriptor, N>
// The company's biggest funding.
template <typename S>
consteval auto get_layout() {
constexpr size_t N = []() consteval {
return nonstatic_data_members_of(^S).size();
}();

std::array<member_descriptor, N> layout;
[: expand(nonstatic_data_members_of(^S)) :]
>> [&, i=0]<auto e>() mutable {
layout = {.offset=offset_of(e), .size=size_of(e)};
++i;
};
return layout;
}

struct X
{
char a;
int b;
double c;
};

int main() {

std::cout << 'n';

constexpr auto layout = get_layout<X>();

std::cout << "Layout of struct X:n";
for (const auto& member : layout) {
std::cout << "Offset: " << member.offset
<< ", Size: " << member.size << 'n';
}

std::cout << 'n';

}


C ++ programı, bir yapının veri öğelerinin düzenini yansıtır. Bu kodun temel amacı, bir yapının bireysel üyelerinin bellek ofsetini ve boyutunu belirlemek ve üretmektir.

Kodun ilk kısmı bir std::array isminde layoutyapının her üyesi için tanımlayıcıların kaydedilmesi gerekir. Bu tanımlayıcılar tek tek elemanların ofsetini ve boyutunu içerir. . [: expand(nonstatic_data_members_of(^S)) :] Yapı, yapının statik olmayan verilerinin üyelerini ilgilendiren bir yapı -programlama için bir yer tutucudur. S yineleme. Bu yapı sadece geçici bir acil durum çözümüdür ve bunu mevcut durumun referans için bir lambda işlevi izler (&) Kayıtlı ve değişken bir dizin i sıfıra başlatıldı. Lambda işlevi daha sonra her bir veri öğesine uygulanır, böylece düzen dizisinde ve dizinde kaydedilen her bir öğenin ofseti ve boyutu i Arttı.

Yapı X Üç veri üyesi ile tanımlanmıştır: aA int isminde b ve bir double isminde c. Bu üyeler yansıma mekanizmasını göstermek için kullanılır.

İçinde main Bu bir işlev olacak get_layout<X>() Şu anda yapı üyelerinin ofseti ve boyutu olan düzen dizisi olarak adlandırılır X geri gelmek. Program daha sonra Strutt düzenini sağlar X Düzen dizisi aracılığıyla selamlayıcıdan çıkın ve her üyenin ofsetini ve boyutunu üretir.

Bu kod, veri yapılarının yönetim yönetimini ve optimizasyonunu anlamak için yararlı olabilecek bir C ++ yapısının veri öğelerinin depolama düzenini yansıtır.

Son olarak, program baskısı şöyle görünüyor:








Yansımaları bir kapta kaydedebilir veya bir algoritma uygulayabilirsiniz.

Veri türlerinin boyutunu görüntüleyin


Aşağıdaki program, bazı entegre veri türlerinin boyutunu belirler.


// getSize.cpp

#include <experimental/meta>
#include <array>
#include <iostream>
#include <ranges>
#include <algorithm>

constexpr std::array types = {^int, ^float, ^double};
constexpr std::array sizes = []{
std::array<std::size_t, types.size()> r;
std::ranges::transform(types, r.begin(), std::meta::size_of);
return r;
}();

int main() {

std::cout << 'n';

std::cout << "Types and their sizes:n";
for (std::size_t i = 0; i < types.size(); ++i) {
std::cout << "Size: " << sizes << " bytesn";
}

std::cout << 'n';

}


Program, farklı başlıkların eklenmesiyle başlar: <experimental/meta> Yansıtma yeteneği için, <array> Dizinin sabit boyutunun desteği için, <iostream> Giriş/çıkış işlemleri için, <ranges> E aralığına dayalı algoritmalar için <algorithm> Genel algoritmalar için.

Beyanname constexpr std::array types Derleme dönemi için yansımalar içeren bir dizi oluşturun int,, float VE double. Bu yansımalar yansıma operatörü ile kullanılır ^ gösterilen.

Daha sonra, beyan tanımlar constexpr std::array sizes Derlemede dizinin boyutunun başka bir çapası types Belirtilen türleri içerir. Bu dizi, bir dizinin bir lambda işlevi ile başlatılır r Aynı boyutta types oluşturuldu. İşlev std::ranges::transform Bu nedenle kullanılır r Operasyon ile doldurmak std::meta::size_of Her yansıma değerinde types Kullanılır. . std::meta::size_of-İşlem, derleme süresi boyunca bir veri türünün boyutunu döndüren bir hedef işlevdir.

. main-Bilat, veri türü dizisi dizinlerinde jet atan bir döngü ile başlar. Her dizin için, bayt boyutu dizisinden karşılık gelen veri türünün boyutunu yayar.








Aralıkların işlevi yerine std::ranges::transform Klasik olabilirsin transform-Algoritmayı kullanın.


std::transform(types.begin(), types.end(), r.begin(), std::meta::size_of);


Sırada ne var?


En son blog yayınları, C ++ 26'daki yansımaya ilk genel bakıştı. Daha sonra daha derin bir vizyon gelecek. Bir sonraki makalemde sözleşmelere odaklanacağım.


(RME)
 
Üst