нет стандартного пространства имен - PullRequest
2 голосов
/ 20 декабря 2009

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

Один из этих недостатков заключается в том, как он работает с компиляторами 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. Глобальное пространство имен загрязнено почти всем, что обычно находится в пространстве имен 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, в котором использовался страшный «using namespace std;» и я получаю ошибку компиляции, потому что это становится «использованием пространства имен», так что, очевидно, не будет работать.

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

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

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

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

1 Ответ

16 голосов
/ 20 декабря 2009

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

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

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

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

...