#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. Не решает вопрос