Czy mogę ponownie zdefiniować makro C++, a następnie zdefiniować je z powrotem?

Używam zarówno biblioteki JUCE, jak i kilku nagłówków Boost w moim kodzie. Juce definiuje" T "jako makro (groan), a Boost często używa" T " w swoich definicjach szablonów. Rezultatem jest to, że jeśli w jakiś sposób włączysz nagłówki JUCE przed nagłówkami Boost, preprocesor rozszerzy makro JUCE w kodzie Boost, a następnie kompilator zostanie beznadziejnie zgubiony.

Utrzymanie mojej pozycji w odpowiedniej kolejności nie jest trudne przez większość czasu, ale może być trudne, gdy masz klasę JUCE, która zawiera kilka innych klas i gdzieś w łańcuchu jeden plik zawiera Boost, a jeśli którykolwiek z plików przed potrzebowałem juce zawierać jesteś w tarapatach.

Moją początkową nadzieją na naprawienie tego było

#undef T

Przed dołączeniem do Boost. Ale problem w tym, że jeśli nie zdefiniuję go ponownie, to inny kod się myli, że "T" nie jest zadeklarowane.

Wtedy pomyślałem, że może mógłbym zrobić jakieś okrągłe # define trickery w ten sposób:

// some includes up here
#define ___T___ T
#undef T
// include boost headers here
#define T ___T___
#undef ___T___
Brzydkie, ale myślałem, że może praca. Niestety nie. Dostaję błędy w miejscach używając" T " jako makra, które
'___T___' was not declared in this scope.

Czy istnieje sposób, aby te dwie biblioteki działały niezawodnie razem?

Author: Brian Tompsett - 汤莱恩, 2009-11-25

3 answers

Jak zauważył greyfade, twoja sztuczka ___T___ nie działa, ponieważ preprocesor jest dość prostym stworzeniem. Alternatywnym podejściem jest stosowanie dyrektyw pragma:

 // juice includes here
 #pragma push_macro("T")
 #undef T
 // include boost headers here
 #pragma pop_macro("T")

To powinno działać w MSVC++ i GCC dodał wsparcie dla pop_macro i push_macro dla kompatybilności z nim. Technicznie rzecz biorąc, jest to zależne od implementacji, ale nie sądzę, aby istniał standardowy sposób chwilowego tłumienia definicji.

 59
Author: Peter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-05 09:13:14

Czy możesz zawinąć bibliotekę w inny include i uwięzić #define t wewnątrz?

Eg:

JUICE_wrapper.h:     
#include "juice.h"
#undef T

main.cpp:    
#include "JUICE_wrapper.h"    
#include "boost.h"

 rest of code....
 11
Author: Martin Beckett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-25 01:00:29

Wtedy pomyślałem, że może mógłbym zrobić jakieś okrągłe # define trickery w ten sposób:

Preprocesor C nie działa w ten sposób. Symbole preprocesora nie są zdefiniowane w tym samym sensie, w jakim dany symbol ma znaczenie, gdy, , np., zdefiniujesz funkcję.

Może pomóc myśleć o preprocesorze jako o silniku zastępującym tekst. Gdy symbol jest zdefiniowany, jest on traktowany jako prosty tekst-zastąp do końca pliku lub do momentu jego niezdefiniowania. Jego wartość nie jest przechowywane w dowolnym miejscu, a więc nie mogą być kopiowane. Dlatego jedynym sposobem, aby przywrócić definicję T po #undef ed jest całkowite odtworzenie jej wartości w Nowym #define później w kodzie.

Najlepsze, co możesz zrobić, to po prostu nie używać Boost lub petycji do twórców JUCE, aby nie używali T jako makra. (Lub, w najgorszym przypadku, napraw to samodzielnie, zmieniając nazwę makra.)

 4
Author: greyfade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-25 00:15:23