Як я можу “не використовувати” простір імен?


86

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

using namespace xyzzy

... заяви в них, які впливають на мій код, коли я цього найменше хочу чи очікую.

Чи є спосіб я якось скасувати / замінити попереднє твердження "за допомогою", щоб уникнути цього.

Можливо...

unusing namespace xyzzy;

3
Ймовірно, вам слід відкрити звіт про помилку з їх системою контролю якості: qc.codegear.com
Kris Kumler

2
До речі, які це автоматично згенеровані заголовки?
Kris Kumler

2
Одного разу C ++ матиме модулі, а включення коду до іншого коду матиме кращі конструкції інкапсуляції. До цього часу існує непростий спосіб обійти це. Розгляньте можливість розміщення власного коду у просторі імен і посилання на нього таким чином.
Тревор Хікі,

Відповіді:


59

Ні. Але є потенційне рішення: якщо ви вкладете директиву include у власний простір імен, наприклад ...

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

... тоді ефекти будь-яких директив використання в цьому заголовку нейтралізуються.

У деяких випадках це може бути проблематично. Ось чому кожен посібник стилю на C ++ настійно рекомендує не вводити директиву "using space names" у заголовочний файл.


1
Загалом, це жахлива ідея. Заголовки C ++ не призначені для включення в поперемінно простір імен, як тут було використано.
Аарон,

24
Це жахлива ідея також включити директиву using у файл заголовка. Це просто пом'якшує цю проблему.
Head Geek

4
Розміщення заголовка у власному просторі імен не є рішенням, оскільки воно змінює значення декларацій у цій бібліотеці. (-1)
Річард Корден

4
Це повністю залежить від того, що оголошено в заголовку.
Head Geek

1
Саме тому це невизначена поведінка.
Kris Kumler

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, включайте: DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE


Але це, здається, не працює належним чином. Принаймні у всіх випадках, я намагався (з BCB6). Потім я повертався до додавання явних просторів імен у конфлікті і - що ще гірше - включав заголовок для уникнення конфліктів імен типів ...
Wolf

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

Ви можете використовувати оператор роздільної здатності для використання іншої змінної простору імен
Narendra kumawat

3
Не вирішує питання
М.М.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.