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

86

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

using namespace xyzzy

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

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

Может быть...

unusing namespace xyzzy;
Родди
источник
3
Вам, вероятно, следует открыть отчет об ошибке в их системе контроля качества: qc.codegear.com
Крис Кумлер,
2
Кстати, какие это автоматически сгенерированные заголовки?
Крис Кумлер
2
Когда-нибудь в C ++ появятся модули, и включение кода в другой код будет иметь более совершенные конструкции инкапсуляции. До тех пор нет простого способа обойти это. Подумайте о том, чтобы поместить свой собственный код в пространство имен и называть его таким образом.
Trevor Hickey

Ответы:

59

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

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

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

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

Главный Компьютерщик
источник
1
В общем, это ужасная идея. Заголовки C ++ не предназначены для включения в альтернативное пространство имен, которое использовалось здесь.
Аарон
25
Ужасная идея также включать директиву using в файл заголовка. Это просто смягчает эту проблему.
Head Geek
4
Размещение заголовка в вашем собственном пространстве имен не является решением, поскольку оно меняет значение объявлений в этой библиотеке. (-1)
Ричард Корден
4
Это полностью зависит от того, что объявлено в заголовке.
Head Geek
1
Именно поэтому это неопределенное поведение.
Крис Кумлер
56

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

Пример:

{
    using namespace xyzzy;

} // stop using namespace xyzzy here

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

jk.
источник
Можете ли вы обернуть включение в такой блок?
Eclipse,
Да, с автоматически сгенерированным кодом этого не произойдет. Быт мыбе он может поменять шаблон на автоматически сгенерированный код?
jk.
Да, это не решает проблему заголовков, использующих пространства имен.
Кип,
К сожалению, это не так. Попробуйте это:
Адам
пространство имен xyzzy {const int i {с использованием пространства имен xyzzy; } // здесь перестаем использовать пространство имен xyzzy
Адам
17

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

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
Затмение
источник
10

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

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

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


источник
1

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

Каспрзол
источник
1
Это, вероятно, вызовет проблемы с изменением имен, если файлы заголовков являются объявлениями библиотеки. Компиляция завершится успешно, но компоновщик не сможет найти определения, поскольку они уже были скомпилированы в другом пространстве имен.
Eclipse,
-1
#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
пожалуйста, объясните свой ответ!
Mazz
вы можете использовать оператор разрешения области видимости, чтобы использовать другую переменную пространства имен
Нарендра Кумават
3
Не отвечает на вопрос
MM