LINUX.ORG.RU

C++: как все-таки работать со стандартными namespace?


0

0

Замучался. Есть ли какое-нибудь идеальное решение при использовании стандартных классов, определенных в неймспейсах?

Можно писать каждый раз с префиксом:
std::string str_;
__gnu_cxx::hash_map map_;

Это долго, громоздко, нечитабельно (и подозреваю, что с __gnu_cxx могут быть проблемы на других компиляторах - тогда все равно придется определять его где-то в одном месте).

Можно писать using std::string, using __gnu_cxx::hash_map. Хоть сам код выглядит лучше, это тоже криво. К тому-же, я пишу библиотеку и использовать using в ее хедерах значит подкладывать змею тому, кто библиотеку юзает. Неужели пихать эти using в каждый класс?

Можно писать using namespace std - но это совсем плохо. Я уже нарывался на косяки с засорением namespace'ов, да и сколько их может быть? std, __gnu_cxx, boost, ... Ужас. Опять же проблема с использованием этого в хедерах.

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

Как быть-то? Подозреваю, что придется писать все с префиксами, а очень не хочется... Было бы неплохо сделать макрос со всеми using и использовать его в начале определения каждого класса и в .cc. Проблем не было бы, но тогда нужно опять же include'ить все.

Можно сделать что-то вроде
#ifdef _GLIBCXX_STRING
using std::string
#endif

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

В общем, п%%дец. Писать с префиксами и не трахать мозг?

anonymous

> Можно писать using namespace std - но это совсем плохо.

А чем это плохо-то? Как я понимаю, оно так и было задумано...

Die-Hard ★★★★★
()

Вдогонку:

> Я уже нарывался на косяки с засорением namespace'ов, да и сколько их может быть? std, __gnu_cxx, boost, ... Ужас. Опять же проблема с использованием этого в хедерах.

Долго думал, заинтриговало... :)

Что такое "засорение namespace'ов"? Зачем включать всегда весь namespace, если требуются два-три имени?

В чем проблема с хедерами? Зачем в них вообще using? (В инлайн-функциях можно и префиксы заюзать).

Короче, я как-то ни разу с подобными проблемами не сталкивался...

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> А чем это плохо-то? Как я понимаю, оно так и было задумано...

Задумано для ленивых. На самом деле очень высока вероятность напороться на косяки, особенно когда используется несколько namespace, например std, __gnu_cxx, boost, Qt, да еще и свое.

anonymous
()
Ответ на: комментарий от Die-Hard

> Что такое "засорение namespace'ов"?

Когда в namespace куча функций, и возможны коллизии. Я, собственно, как раз обернул все свое в namespace после того, как программа перестала собираться со странными ошибками - а проблема была в том, что что-то мое конфликтовало с чем-то сторонним. Что именно уже не помню, но там было Qt3 и сишные библиотеки типа Curl.

> В чем проблема с хедерами?

Если в хедере использовать using, он будет распространяться и на тех, кто этот хедер подключает. Учитывая написанное выше и то, что в проекте, использующем либу може использоваться вообще непредсказуемый набор имен, неймспейсов и макросов, ты подложишь ему офигенную свинью, использовав у себя using. Этого можно избежать, запихнув using в свой класс:

class MyClass {
using std::string;
private:
string str_;
};

То же можно делать с отдельными методами. Это работает без проблемы, но выглядит уродливо :/

anonymous
()

Кстати, заодно, дайте примеров C++'ных библиотек кроме Qt.
Хочу посмотреть как у людей сделано.

anonymous
()
Ответ на: комментарий от anonymous

> Когда в namespace куча функций, и возможны коллизии.

Коллизии разрешаются в порядке поступления. Глюков при этом получается не больше, чем от перегрузки функций. Если придерживаться разумной модульности и не мешать все в кучу, то никаких проблем не возникает. Просто не надо говорить using сразу на все "на всякий случай".

> Если в хедере использовать using ...

То ССЗБ.

> Это работает без проблемы, но выглядит уродливо :/

ИМХО это не более уродливо, чем весь ЦеПП. Это именно так и было задумано.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> Коллизии разрешаются в порядке поступления. Глюков при этом получается не больше, чем от перегрузки функций. Если придерживаться разумной модульности и не мешать все в кучу, то никаких проблем не возникает. Просто не надо говорить using сразу на все "на всякий случай".

Замечательно. Я это написал в первом посте. Вопрос был в том, есть ли альтернатива пачке using в каждом файле/классе. Я не прочь бы услышать что-нибудь про precompiled headers, например.

Хотя по всей видимости проще всего использовать std::

anonymous
()

Писать с префиксами, это повышает читабельности и понимаемость кода. Сам себе потом спасибо скажешь.

Если так стрёмно писать длинные строчки, используй синонимы для неймспейсов:

namespace fs = boost::filesystem;

Кроме того, что мешает пихать using не в хедеры, а в cpp-файлы?

annoynymous ★★
()

После прочтения книжки Липмана следую следующему правилу:
- в хедерах указывать namespace полностью (std::string)
- в файлах с реализацией класса использовать using (using std::string)

php-coder ★★★★★
()
Ответ на: комментарий от annoynymous

Ну в общем как я и думал. На деле совсем неплохо. Спасибо всем большое.

anonymous
()

а по моему чтото типа boost::dynamic_pointer_cast<std::vector<boost::shared_ptr<int>>>(... очень даже эстетично

anonymous
()
Ответ на: комментарий от anonymous

> Замечательно. Я это написал в первом посте. ...

Ну, я и процитировал, выразив недоумение, чего тут стремного такого :-)

Короче, я не вижу альтернатив "пачке using в каждом файле/классе". Более того, я не вижу в этом ни малейших проблем.

Разумеется, ИМХО.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

>> boost::dynamic_pointer_cast<std::vector<boost::shared_ptr<int>>>(... очень даже эстетично

> :-) И я про то же!

Фигассе чувство прекрасного o_O

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.