2010-11-20 23 views
17

Mam zamiar napisać duży projekt w języku C++ 11.Biblioteka refleksyjna C++ 11

Poszukuję dobrej biblioteki C++ 11/C++ i znalazłem kilka różnych bibliotek, ale większość z nich po prostu nie jest aktualizowana przez ostatnie kilka lat lub ich funkcjonalność jest bardzo ograniczona.

Czy możesz mi powiedzieć, czy istnieje naprawdę dobra biblioteka dla C++ 1/C++ do refleksji? (Chcę mieć odbicie statyczne i dynamiczne, znać jak najwięcej informacji o metodach, klasach itp., Można dynamicznie dodawać i uzyskiwać dostęp do metod itd.).

A może C++ 11 zapewnia dodatkowe funkcje, które pomogą do lepszego projektowania bibliotek refleksyjnych i czy powinienem napisać to sam? (Nie znalazłem jednak informacji na ten temat).

+8

Wygląda na to, że Twój projekt nie pasuje do Twojego wyboru języka. – ybungalobill

+0

To jest [podobne pytanie] (http://stackoverflow.com/questions/41453/how-can-i-add-reflection-to-a-c-application). Szukałem też i znalazłem [CAMP] (https://github.com/tegesoft/camp). Mam [fork] (https://github.com/billyquith/camp), który usuwa zależność Boost i używa C++ 11 zamiast tego. – Nick

+0

Nie jestem pewien, jak bardzo zmieniło się to przez lata, ale możesz być w stanie osiągnąć niektóre cechy refleksji dzięki starannemu projektowaniu. Na przykład: wzór dekoratora, aby dodać/zmodyfikować zachowanie w CT lub RT (https://en.wikipedia.org/wiki/Decorator_pattern); SFINAE wykrywa funkcję w CT https://stackoverflow.com/a/29319078/1043529; dep. inwersja (https: //en.wikipedia.org/wiki/Dependency_inversion_principle), aby wyszukać określone metody (CRTP i static_cast dla CT, dynamic_cast dla RT) i więcej. Pełna refleksja dla prawdziwie arbitralnych typów? Wybierz swoje bitwy, ten jest pod górkę. –

Odpowiedz

9

C++ nie jest najlepszym językiem do refleksji. C++ 0x tak naprawdę to nie zmienia. Możesz uzyskać ograniczone wsparcie dla statycznego odbicia za pomocą cech typu, a nawet możesz użyć SFINAE do statycznego określenia, czy dana klasa ma określoną funkcję członka lub zmienną członka. Ale to naprawdę to.

Odbicie dynamiczne jest poważnie ograniczone. Możesz uzyskać typ klasy w czasie wykonywania, korzystając z urządzeń <typeinfo>, ale to wszystko.

Jeśli chodzi o odbicie statyczne, możliwość generycznego powtarzania danej klasy i uzyskania każdej zmiennej/funkcji członka nie jest możliwa bez poważnych kompromisów. Boost.Fusion udaje się to zrobić, zapewniając makra, które pozwalają ci związać obiekt z kaczym kontenerem. Klasa std::tuple lub boost::tuple w naturalny sposób zapewnia refleksję podczas kompilacji - innymi słowy, możesz statycznie iterować po krotce i określić typ każdego elementu. Daje to coś zbliżonego do refleksji na temat kompilacji nad arbitralnymi typami agregującymi. Niestety, nie jest to tak wygodne, jak gdyby w przypadku klas arbitralnych istniało wbudowane wsparcie dla refleksji.

5

Wygląda na to, że istnieje biblioteka, która spełnia twoje "szerokie" wymagania. Spójrz na Mirror: Boost.Mirror. Zauważ, że oficjalnie NIE jest to częścią wzmocnienia. Możesz również rzucić okiem na inne biblioteki: Reflective Programming.

+0

Dziękujemy! To jest naprawdę interesujące, przyjrzę się temu bliżej :) –

+0

+1 wygląda naprawdę dobrze - z kilkoma drobnymi poprawkami, wydaje się działać z gcc 4.7.2 – kfmfe04

3

QT ma prymitywną formę refleksji, prawdopodobnie chcesz wziąć na siebie łup.

+0

Ok będę :) Dlaczego jest prymitywny? –

+0

Cóż, daleko mu do elastyczności innych języków, takich jak java i C#. Działa również tylko na klasach dziedziczących po QObject. Nie wiem o innych ograniczeniach. –

3

Cóż, w zależności od tego, co masz po, można zbudować własny ontop z python i clang python powiązań. Istnieje kilka przykładów, takich jak mój własny https://github.com/nevion/metapod - inne istnieją, jeśli wystarczająco mocno się psujesz i w pewnym sensie to właśnie robi narzędzie QT MOC - z wyjątkiem tego, że klang sprawia, że ​​zadanie jest o wiele łatwiejsze. Jedną z fajnych rzeczy na temat tego podejścia jest to, że działa ono dla wszystkich kompilatorów, ponieważ generujesz tylko standardowy kod z szablonami mako - ale oznacza to również, że nie jest w pełni zautomatyzowany - więc istnieje kompromis i nie radzimy sobie z każdym metaprogramowaniem/potrzeba odbicia. Jak powiedział Charles Salvia, C++ nie jest najlepszym językiem do refleksji, więc musisz wziąć to, co możesz dostać.