2009-04-07 3 views
5

Wir programmieren eine Protokollierungsbibliothek, die sich in einer .hpp-Datei befindet. Wir möchten <tr1/unordered_map> einschließen (wenn der Compiler TR1 unterstützt) oder den Standard <map> andernfalls. Gibt es eine Standardmethode zur Überprüfung während der Kompilierung, wenn tr1 verfügbar ist oder nicht?Wie man während des Kompilierens nach TR1 sucht?

Ich dachte, dass auf die gleiche Weise, die das "__cplusplus" definieren Symbol vorhanden ist, könnte ein "__cxx__tr1" oder so ähnlich definiert worden sein. Ich habe das in den Entwürfen für TR1 nicht gesehen, also nehme ich an, dass es nicht vorhanden ist, aber ich wollte zuerst nur für den Fall fragen.

Als Anmerkung, wenn diese Definitionen nicht existieren, wäre es keine schlechte Idee, sie in die Vorschläge selbst aufzunehmen.

Antwort

2

Wenn Sie Konfigurations-Tools wie Autotools verwenden können Sie versuchen, einen Test wie zu schreiben:

AC_CHECK_HEADER(tr1/unordered_map,[AC_DEFINE([HAVE_TR1],[],["Have tr1"])],[]) 
AC_CHECK_HEADER(unordered_map,[AC_DEFINE([HAVE_CXX0X],[],["Have C++0x"])],[]) 

Und dann diese definiert in Ihrem Code verwenden.

Im Allgemeinen __cplusplus Makro sollte Ihnen Standard-Versionsnummer, aber es gibt keinen Compiler, der Ihnen 100% Standard-Implementierung gibt ... So schreiben Sie konfigurieren Makros.

Leider ist dies nur recht zuverlässig Weg, um solche Dinge zu überprüfen, es sei denn, Sie 1001 #ifdef für jeden Compiler schreiben wollen (was Auftrieb der Fall ist)

Und dann:

#include "config.h" 
#ifdef HAVE_CXX0X 
# include <unordered_map> 
    typedef std::unordered_map<foo,bar> my_map; 
#elif HAVE_TR1 
# include <tr1/unordered_map> 
    typedef std::tr1::unordered_map<foo,bar> my_map; 
#else 
# include <map> 
    typedef std::map<foo,bar> my_map; 
#endif 
+0

OK, das war eine Option, die ich vermeiden wollte, da ich nur eine .hpp-Datei freigeben und ausführen möchte. Für diese "fast Standard" -Dinge würde ich einen einfachen Vergleich bevorzugen, anstatt eine vollwertige Konfiguration ausführen zu müssen. –

+0

Ich akzeptiere diese Antwort, da es scheint, dass es keinen Weg gibt, und dies scheint der bessere Weg zu sein ... –

2

GCC-4.3 hat:

#define __GXX_EXPERIMENTAL_CXX0X__ 1 

Aber das ist natürlich nicht Standard.

+0

Dieses Makro ist definiert, wenn Sie g ++ -std = C++ 0x verwenden und Sie haben dann unordered_map in std :: unordered_map. Andernfalls (no -std = C++ 0x) haben Sie diese Definition nicht, aber Sie können immer noch die Klassen include und std :: tr1 :: unordered_map verwenden. – Artyom

+0

Ja, aber wie andere darauf hingewiesen haben, kann dies nur während der Konfiguration getestet werden. Alle anderen Versionen von GCC vor 4.3 werfen einen Fehler, wenn der Schalter -std angegeben wird. – greyfade

1

Eine Bibliothek, mit der ich mich beschäftige, benötigt einige Klassen, die zu TR1 von Boost hinzugefügt wurden und TR1 bevorzugen, falls verfügbar. Die Lösung (eine Unix-basierte Bibliothek) besteht darin, die Überprüfungen in das configure-Skript zu schieben.

Also mit anderen Worten, nein, nichts tragbares, das ich kenne. Das heißt, wenn Sie unter Unix sind, funktionieren die Konfigurations-Skripts gut genug.

2

Siehe ISO C++ (WG21) Papier N1575. Dieses Papier wurde von TR1 ohne Ersatz entfernt. Es gibt also keine offizielle Möglichkeit, TR1 zu erkennen.

+0

+1. Interessant. Ich wusste nicht ... Schade. –

0

Unter der Annahme, man VS2010 verwenden, oder eine Suite, die TR1 zur Verfügung hat, was passieren würde, wenn man

täte
#include "boost/tr1/unordered_map.hpp" 
... 
std::tr1::unordered_map<...> uMap; 

Was wäre die Art von uMap sein?

Verwandte Themen