2009-12-20 2 views
2

У нас есть приложение C++ с разумным размером, которое на этом этапе довольно старое, поэтому у него есть несколько причуд.no std namespace

Один из этих причуд в том, как он имеет дело с компиляторами C++, которые используют стандартную библиотеку предварительной классификации. Существует один файл заголовка, который должен разрешить любые различия между совместимым с стандартами компилятором и этим несоответствующим компилятором. По разным причинам мы не можем/не хотим останавливать поддержку этого компилятора.

#include <vector> 
#include <set> 
#if defined(NO_STD_LIB) 
    #include <iostream.h> 
#else 
    #incude <iostream> 

    using std::string; 
    using std::cout; 
    using std::vector; 
    using std::cout; 
#endif 

Вы можете использовать это следующим образом

#include stl.h 
int main() { 
    vector<string> foo; 
    ..... 
    return 0; 
} 

Есть 2 основные проблемы с этим подходом:

  1. каждой компиляции блок, который включает в себя std.h должен собрать много ООН необходимые кода (и мы стараемся сократить время компиляции как можно больше на минуту)
  2. Глобальное пространство имен загрязнено почти всем, что не было mally быть в пространстве имен std.

Я действительно хотел бы рассмотреть оба эти пункта как часть проекта очистки кода. Первая - действительно важная причина для этого.

Поскольку мы должны поддерживать этот старый компилятор, тогда наш код всегда должен избегать столкновения имен с вещами, которые он предоставляет в его стандартной библиотеке, так что точка 2 не очень актуальна, хотя я бы хотел увидеть решение это работает, когда/если мы можем, наконец, отказаться от поддержки.

Моей идеей до сих пор является разбиение супер заголовка на набор меньших заголовков. например stl_vector, stl_iostream, stl_set и т. д. Таким образом, мы можем включать только те части стандартной библиотеки, которые нам интересны. Эти имена файлов соответствуют шаблону std-заголовков, но с легко просматриваемым префиксом. Поэтому, когда придет время свалить компилятор-нарушитель, будет легко найти префикс и удалить его.

Я думаю, что исправить проблему 1 достаточно легко.

Моя реальная проблема фиксации вопрос 2. Я замышлял коснуться как этот

#if defined(NO_STD_LIB) 
    #include <iostream.h> 
    #define std 
#else 
    #include <iostream> 

тогда мы могли бы закодировать следующим образом:

#incude "stl_iostream" 

int main() { 
    std::string foo("bar"); 
    std::cout << foo << std::endl; 
} 

И что почти сработало. Там, где не было стандартного пространства имен, #define std сделал std :: string разложением на: string, и жизнь была хорошей.

Затем я попробовал это с .cc файлом, который использовал ужасное «использование пространства имен std;» и я получаю ошибку компиляции, потому что это становится «использованием пространства имен», так что, очевидно, это не сработает.

Теперь очевидно, что я мог запретить людям писать «using namespace std;», но, насколько это следует избегать в заголовках, иногда полезно в файлах .cc, где вы сильно используете множество STL-классов.

Так что, наконец, на вопрос. Существует ли стандартная идиома для решения этой проблемы. Или, если нет стандартного способа справиться с этим, то какие трюки вы используете для поддержки компиляторов, которые используют стандартную стандартную библиотеку.

Я думал об использовании предварительно скомпилированных заголовков для решения проблемы скорости компиляции, но мы нацеливаемся на разные компиляторы, и усилия по получению этой работы над всеми из них могут означать, что это не стоит нашего времени делать это.

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

ответ

16

Вы можете попробовать:

#if defined(NO_STD_LIB) 
namespace std { 
    using ::string; 
    using ::cout; 
    using ::vector; 
    using ::cout; 
} 
#endif 

Тогда std::string будет работать.

Было бы намного лучше, если бы директива using namespace ::; существовала на языке; однако это не так.

Смежные вопросы