Programlama Dili: C++26'da Yansıma | merhaba çevrimiçi

Adanali

Active member
Programlama Dili: C++26'da Yansıma | merhaba çevrimiçi


  1. Programlama dili: C++26'da yansıma

Yansıma, bir programın kendi yapısını ve davranışını inceleme, dikkate alma ve değiştirme yeteneğidir.


Duyuru









C++'da yansıma daha fazladır. İşte tekliften iki ifade (P2996R5).








Rainer Grimm uzun yıllardır yazılım mimarı, ekip ve eğitim yöneticisi olarak çalışmaktadır. C++, Python ve Haskell programlama dilleri üzerine makaleler yazmaktan hoşlanıyor, aynı zamanda özel konferanslarda sık sık konuşmaktan da hoşlanıyor. Modern C++ adlı blogunda C++ tutkusunu yoğun bir şekilde ele alıyor.







Biz sadece program yapısını gözlemlemek istemiyoruz: aynı zamanda bu gözlemlere dayalı kod üretimini de kolaylaştırmak istiyoruz. Bu kombinasyona bazen “dönüşlü metaprogramlama” adı verilir, ancak WG21 tartışmasında “yansıtma” terimi genellikle gayri resmi olarak aynı genel fikre atıfta bulunmak için kullanılmıştır.

Bu önerinin derleme zamanı yansıması ve metaprogramlamaya ilişkin son oyun olması amaçlanmamıştır. Bunun yerine, zamanla daha güçlü özelliklerin aşamalı olarak ekleneceği kullanışlı bir çekirdek olmasını bekliyoruz. Özellikle, geri kalan işlevlerin çoğunun veya tamamının P1240R2'de araştırıldığına ve kod eklemenin (bkz. [P2237R0]) takip edilmesi arzu edilen yönlerdir.

Tarih


C++'ta yansımanın geçmişi şablon metaprogramlamasına dayanmaktadır. Model metaprogramlaması, yansıma gibi 1994 civarında başladı. C++98, çalışma zamanı yansımasını (RTTI) ve işlev modeli türü çıkarımını aldı. C++11'deki veri türü kitaplığı, C++'ın işlevselliğini geliştirmiştir. C++26'da muhtemelen genel yansıma desteği alacağız.

Benim stratejim


Reflection'ı C++26'ya tanıtırken P2996R5 teklifine güveneceğim ve P2996R5 teklifindeki örnekleri kullanacağım.

Öncelikle yansıma değerinden gramer unsurlarına ileri geri atlamak istiyorum.

Dilbilgisi unsurları Yansıma değeri


Aşağıdaki program dilbilgisi alanında başlar, yansıma alanına geçer ve dilbilgisi alanına geri döner.


// forthAndBack.cpp (P2996R5)

#include <iostream>&#13;
#include <cassert>&#13;
#include <concepts>&#13;
&#13;
int main() {&#13;
constexpr auto r = ^int;&#13;
typename[:r:] x = 42; // Same as: int x = 42;&#13;
typename[:^char:] c = '*'; // Same as: char c = '*';&#13;
&#13;
static_assert(std::same_as<decltype(x), int>);&#13;
static_assert(std::same_as<decltype(c), char>);&#13;
assert(x == 42);&#13;
assert(c == '*');&#13;
}


  • ^: Reflexionsoperator işleneninden bir yansıma değeri üretir (^int VE ^char)
  • [: refl :]: Splicer yansıma değerinden bir dilbilgisi öğesi oluşturur ([:r:] VE [:^char:])
  • Reflexionswert program öğelerinin sabit bir ifade olarak temsilidir
Çağrı ^gramOper veri türüyle bir yansıma oluşturun: std::meta::info. std::same_as bu bir kavram.

Yalnızca dilbilgisi ve düşünme alanları arasında atlamak pek mantıklı değil. İşte programın daha ayrıntılı bir dökümü enumString.cpp:

Numaralandırma Sicim


Enum => Dize

Aşağıdaki örnek, bir enum değerini dizeye dönüştürür:


// enumString.cpp

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


template<typename E>
requires std::is_enum_v<E> // (1)
constexpr std::string enum_to_string(E value) {
std::string result = "<unnamed>";
[:expand(std::meta::enumerators_of(^E)):] >> // (2)
[&]<auto e>{
if (value == [:e:]) {
result = std::meta::identifier_of(e); // (3)
}
};
return result;
}


int main() {

std::cout << 'n';

enum Color { red, green, blue };
std::cout << "enum_to_string(Color::red): " << enum_to_string(Color::red) << 'n';
// std::cout << "enum_to_string(42): " << enum_to_string(42) << 'n';

std::cout << 'n';

}


(1)'de veri türü özelliğini kullanıyoruz std::is_enum olup olmadığını kontrol ettim value bu bir numaralandırıcıdır. İfade ^E (2)'deki yansıma değeri üretir. fonksiyon expand aynı satırda göz ardı edilebilir. Mevcut uygulamada genişletme talimatları eksik.

Fonksiyonlar std::meta::enumerators_of VE std::meta::enumerators_of (2) ve (3)'teki metafonksiyonlardır. Yalnızca derleme zamanında çalıştırılabilirler çünkü bunlar consteval beyan edilir.

İşte bazı meta işlevler.


namespace std::meta {
consteval auto members_of(info type_class) -> vector<info>;
consteval auto bases_of(info type_class) -> vector<info>;

consteval auto static_data_members_of(info type_class) -> vector<info>;
consteval auto nonstatic_data_members_of(info type_class) -> vector<info>;

consteval auto subobjects_of(info type_class) -> vector<info> {
auto subobjects = bases_of(type_class);
subobjects.append_range(nonstatic_data_members_of(type_class));
return subobjects;
}

consteval auto enumerators_of(info type_enum) -> vector<info>;
}


Tüm meta işlevler bir tane verir std::vector Geriye. Reflection, veri türlerini analiz etmek ve kod oluşturmak için birçok meta işlev sağlar.

Numaralandırma h3>
Ters adımların kullanılması String'i Enum'a dönüştürür:


template <typename E>
requires std::is_enum_v<E>
constexpr std::eek:ptional<E> string_to_enum(std::string_view name) {
template for (constexpr auto e : std::meta::enumerators_of(^E)) {
if (name == std::meta::identifier_of(e)) {
return [:e:];
}
}

return std::nullopt;
}


Bir sonraki adım nedir?


Yansıma birçok meta işlev sunar. Bir sonraki yazımda bunları uygulayacağım.


(Ben)

 
Üst