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


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

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


Можете ли вы обернуть включение в такой блок?
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


Но, похоже, это не работает должным образом. По крайней мере, во всех случаях я пробовал (с 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.