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


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.