C ++ 26'da Yansıma: Enum ve Sınıflar için Meta Futbol

Adanali

Active member
C ++ 26'da Yansıma: Enum ve Sınıflar için Meta Futbol


  1. C ++ 26'da Yansıma: Enum ve Sınıflar için Meta Futbol

C ++ 26'da yansıma girişinden ve Meta Works'ün temel tanıtımından sonra, bu sefer enum ve sınıflar.








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.







Hedefin adları, bir numaranın veya sınıfın unsurlarına erişim için çalışır.








Bir numaranın öğelerine erişim


Aşağıdaki program Daveed VanDdevoorde Programına dayanmaktadır. Daveed, C ++ yansımasının babalarından biridir ve bu örneği “C ++ yansıması üzerine yansımalar” sunumunda kullanmıştır.

Program bir numaradan geçer ve her bir numaralandırıcı için ad ve değeri gösterir.


// daveed.cpp

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

template<typename E>
struct enum_item {
std::string_view name;
E value;
};

template<typename E>
consteval auto get_enum_data() {
std::array<enum_item<E>, std::meta::enumerators_of(^E).size()> result;
int k = 0;
for (auto mem: std::meta::enumerators_of(^E))
result[k++] = enum_item<E>{ std::meta::identifier_of(mem), std::meta::extract<E>(mem) };
return result;
}

enum MyEnum {
x,
y,
e = -1,
z = 99
};

int main() {

std::cout << 'n';

std::cout << "members of " << std::meta::identifier_of(^MyEnum) << 'n';
for (auto x: get_enum_data<MyEnum>()) {
std::cout << " " << x.name << " = " << (long)x.value << 'n';
}

std::cout << 'n';

}


Sağlanan kod snipper, derleme sırasında kontrol ve işleme listesi türleri için C ++ 'da deneysel meta programlama işlevselliğinin kullanımını göstermektedir. Kod, gerekli müdahalenin eklenmesiyle başlar:array> Bir dizi desteği içinexperimental/meta> Meta programlama hizmet programları için eiostream> Giriş çıkış işlemleri için.

. enum_item STUD modeli, bir liste öğesinde bilgi içerecek şekilde tanımlanır. İki öğe içerir: name bir std::string_viewliste öğesinin adını temsil eden e valueVeri türü listesi listesinin değeri E İçerir.

. get_enum_data Fonksiyon modeli gibi consteval İşaretlenmiş, yani derleme döneminde değerlendirildiği anlamına gelir. Bu işlev bir dizi oluşturur enum_item-Belirli bir liste türü için yapı E. Kullanın std::meta::enumerators_of-Bir liste türünün listeleme öğelerini hatırlamak ve geçin. Her liste değeri için bir tane oluşturun enum_item Listenin adı ve değeri ile, std::meta::identifier_of E adını elde etmek için kullanılır std::meta::extractDeğer elde etmek için. Ortaya çıkan dizi daha sonra döndürülür.

. MyEnum-T sayım listenin dört öğesi ile tanımlanır: y,, x,, e (Açıkça ayarlanmış) e z (açıkça 99'a ayarlanmıştır). Bu liste, hedef programlama işlevlerini göstermek için örnek olarak kullanılır.

İçinde main-Kod başlangıçta biçimlendirme amacıyla yeni bir satır yayar. Yani liste türünün adı MyEnum yardımıyla std::meta::identifier_of üretme. Bir sonraki olacak get_enum_data<MyEnum>() Diziye çağrıldı enum_item-İçin yapılar MyEnum Bu diziden arayın ve geçer. Her biri için enum_item Liste öğesinin adı ve değeri çıktıdır. Değer, tutarlı bir çıktının biçimlendirilmesi içindir. long dönüştürüldü. Son olarak, biçimlendirme için başka bir çizgi kesintisi yapılır.

Genel olarak, bu kod, liste türlerini incelemek ve bu nedenle süre için kullanılabilecek adlar ve liste değerleri gibi yararlı meta veriler oluşturmak için derleme sırasında yansımanın nasıl kullanılabileceğini gösterir.

İşte programın baskısı:









Benim küçük denemem



Bu açıklama, Microsoft AI aracının co -lafot ile oluşturuldu. İtiraf etmeliyim ki etkilendim çünkü açıklanan işlevsellik yepyeni.

Bir sınıfın öğelerine erişim


Aşağıdaki program, bir sınıfın öğelerine erişmenin iki yolunu göstermektedir: dizin ve ad aracılığıyla.


// reflectionClass.cpp

#include <experimental/meta>
#include <iostream>

struct Base {
int i{};
void inc(int& j){ j++; }
};

consteval auto number(int n) {
//return std::meta::nonstatic_data_members_of(^Base)[n];
return std::meta::members_of(^Base)[n];
}


consteval auto named(std::string_view name) {
for (std::meta::info field : std::meta::members_of(^Base)) {
if (std::meta::has_identifier(field) && std::meta::identifier_of(field) == name)
return field;
}
return std::meta::info{};
}


int main() {

std::cout << 'n';

Base base;
base.[:number(0):] = 1;
std::cout << "base.i= " << base.i << 'n';
base.[:number(1):](base.i);
std::cout << "base.i= " << base.i << 'n';

std::cout << 'n';

base.[:named("i"):] = 3;
std::cout << "base.i= " << base.i << 'n';
base.[:named("inc"):](base.i);
std::cout << "base.i= " << base.i << 'n';

}



Base Düşünmek istediğim sınıf. Hedef çalışıyor “number” VE “named“Gerekli bilgileri sağlayın.

  • "number": std::meta::members_of(^Base)[n] Elemanı verir n itibaren Base Geriye doğru. Aksine, var “number": std::meta::nonstatic_data_members_of(^Base)[n] Statik olmayan veri öğesi n itibaren Base Geriye doğru. Yansıma kütüphanesinin ayrıca bir sınıfın tüm statik veri öğelerinin hatırlanabileceği bir hedefi vardır: std::meta::static_data_members_of(^Base)[n]
  • namend: tüm unsurları yineleyin Base ve öğeyi adla verir name Geriye doğru: std::meta::identifier_of(field) == name
Şimdi ana programa atlıyorum. Eleman i itibaren Base Arttı. Veya değeri atayarak veya işlevi arayarak inc. Bağımsız endeks veya adın kullanımı, derleme dönemi için bir hataya yol açar:[:member_number(10):] = 1).

Son olarak, programın baskısını burada gösteriyorum:








Sırada ne var?


Bir sonraki makalemde C ++ 26'da yansıma ile oynamaya devam ediyorum.


(RME)
 
Üst