Как я могу «отключить» пространство имен?

#c #namespaces

#c #пространства имен #c builder

Вопрос:

Одна из причуд моей системы разработки (Codegear C Builder) заключается в том, что некоторые автоматически сгенерированные заголовки настаивают на наличии…

 using namespace xyzzy
  

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

Есть ли способ, которым я могу каким-то образом отменить / переопределить предыдущий оператор «using», чтобы избежать этого.

Возможно…

 unusing namespace xyzzy;
  

Комментарии:

1. Вероятно, вам следует открыть отчет об ошибке в их системе контроля качества: qc.codegear.com

2. Кстати, какие это автоматически сгенерированные заголовки?

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

Ответ №1:

Нет. Но есть потенциальное решение: если вы заключите свою директиву include в отдельное пространство имен, например, так…

 namespace codegear {
    #include "codegear_header.h"
} // namespace codegear
  

…затем эффекты любых директив using в этом заголовке нейтрализуются.

В некоторых случаях это может быть проблематично. Вот почему каждое руководство по стилю C настоятельно рекомендует не помещать директиву «using namespace» в заголовочный файл.

Комментарии:

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

2. Включать директиву using в заголовочный файл — ужасная идея. Это просто устраняет эту проблему.

3. Размещение заголовка в вашем собственном пространстве имен не является решением, поскольку оно изменяет значение объявлений в этой библиотеке. (-1)

4. Это полностью зависит от того, что объявляется в заголовке.

5. Именно поэтому это неопределенное поведение.

Ответ №2:

Нет, вы не можете отключить пространство имен. Единственное, что вы можете сделать, это поместить using namespace оператор — в блок, чтобы ограничить его область действия.

Пример:

 {
    using namespace xyzzy;

} // stop using namespace xyzzy here
  

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

Комментарии:

1. Можете ли вы обернуть включение в блок, подобный этому?

2. Да, это не будет с автоматически сгенерированным кодом. Может быть, он может изменить шаблон для автоматически сгенерированного кода?

3. Да, это на самом деле не решает проблему, с которой он сталкивается с заголовками, использующими пространства имен.

4. К сожалению, это не так. Попробуйте это:

5. пространство имен xyzzy{ const int i{ используя пространство имен xyzzy; } // прекратите использовать пространство имен xyzzy здесь

Ответ №3:

Возможно, вы застряли, используя явные пространства имен в конфликтах:

 string x; // Doesn't work due to conflicting declarations
::string y; // use the class from the global namespace
std::string z; // use the string class from the std namespace
  

Ответ №4:

Для дальнейшего использования: начиная с версии XE, появилось новое значение, которое вы можете #define, чтобы избежать страшного using namespace System; int include : DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE

Комментарии:

1. Но, похоже, это работает неправильно. По крайней мере, во всех случаях, которые я пробовал (с BCB6). Затем я прибегал к добавлению явных пространств имен при конфликте и — что еще хуже — включал заголовок, чтобы избежать конфликтов имен типов…

Ответ №5:

Как насчет использования sed, perl или какого-либо другого инструмента командной строки как части вашего процесса сборки для изменения сгенерированных заголовков после их создания, но до их использования?

Ответ №6:

Быстрый эксперимент с Visual Studio 2005 показывает, что вы можете поместить эти заголовки в свое собственное именованное пространство имен, а затем use то, что вам нужно из этого пространства имен (но не use все пространство имен, поскольку оно вводит пространство имен, которое вы хотите скрыть.

Комментарии:

1. Это, вероятно, вызовет проблемы с искажением имен, если заголовочные файлы являются объявлениями для библиотеки. Компиляция завершится успешно, но компоновщик не сможет найти определения, поскольку они уже были бы скомпилированы в другом пространстве имен.

Ответ №7:

 #include<iostream>
#include<stdio.h>
namespace namespace1 {
    int t = 10;
}
namespace namespace2 {
    int t = 20;
}
int main() {
using namespace namespace1;
    printf("%d" , t);
    printf("%d" , namespace2::t);
}
  

Комментарии:

1. пожалуйста, объясните свой ответ!

2. вы можете использовать оператор разрешения области для использования другой переменной пространства имен

3. Не решает вопрос