2009-04-07 4 views
5

Мы программируем библиотеку протоколирования, которая хранится в файле .hpp. Мы хотели бы включить <tr1/unordered_map> (если компилятор поддерживает TR1,) или стандарт <map> в противном случае. Существует ли стандартный способ проверки во время компиляции, если tr1 доступен или нет?Как проверить TR1 во время компиляции?

Я думал, что так же, как присутствует символ «__cplusplus», может быть определено «__cxx__tr1» или что-то в этом роде. Я не видел этого в проектах для TR1, поэтому я предполагаю, что его нет, но я хотел сначала спросить на всякий случай.

В качестве примечания, если эти определения не существуют, было бы неплохо включить их в предложения сами.

ответ

2

Если вы используете какие-либо конфигурации инструментов, таких как Autotools вы можете попробовать написать тест, как:

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

А затем использовать эти определяет в своем коде.

В общем случае __cplusplus макрос должен предоставить вам стандартный номер версии, но нет компилятора, который дает вам 100% стандартную реализацию ... Таким образом, напишите макросы configure.

К сожалению, это только достаточно надежный способ проверить такие вещи, если вы не хотите, чтобы написать 1001 #ifdef для каждого компилятора (что подталкивание делает)

А потом:

#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

ОК, это был вариант, которого я хотел избежать, так как хочу просто выпустить файл .hpp и запустить. Для этих «почти стандартных» вещей я предпочел бы простое сравнение, а не необходимость запуска полноценной конфигурации. –

+0

Я принимаю этот ответ, поскольку кажется, что нет способа, и это, кажется, лучший способ ... –

2

НКУ-4,3 имеет:

#define __GXX_EXPERIMENTAL_CXX0X__ 1 

Но это, очевидно, не стандарт.

+0

Этот макрос определен, если вы используете g ++ -std = C++ 0x, а затем у вас есть unordered_map в std :: unordered_map. В противном случае (no -std = C++ 0x) у вас нет этого определения, но вы по-прежнему можете использовать класс include и std :: tr1 :: unordered_map. – Artyom

+0

Да, но, как указывали другие, это то, что можно проверить только во время настройки. Все остальные версии GCC до 4.3 выдает ошибку при задании этого ключа -std. – greyfade

1

Одна библиотека, с которой я сталкиваюсь, требует использования некоторых классов, которые были добавлены в TR1 из Boost, предпочитая TR1, если он доступен. Решение (являющееся библиотекой на основе Unix) заключается в том, чтобы перетаскивать проверки в скрипт configure.

Так, другими словами, нет, ничего портативного, о котором я знаю. Тем не менее, если вы работаете в Unix, скрипт configure проверяет работу достаточно хорошо.

2

См ISO C++ (WG21) бумага N1575. Этот документ был снят с TR1 без замены. Таким образом, нет официального способа обнаружения TR1.

+0

+1. Интересно. Я не знал ... Жаль. –

0

Предполагая, что один использует VS2010, или любой пакет, который имеет TR1 доступны, что случилось бы, если бы нужно было сделать

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

Что бы тип uMap быть?