Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/55: Рейтинг темы: голосов - 55, средняя оценка - 4.62
1 / 1 / 0
Регистрация: 07.04.2016
Сообщений: 40

Как именно работает директива using?

10.10.2016, 20:54. Показов 11117. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, уважаемые форумчане! Я изучаю основы языка C++ по книге С.Прата. Наткнулся на такой отрывок: "Директива using делает доступными все имена из пространства имен. Применение директивы using равносильно объявлению имен в наименьшей декларативной области, которая содержит объявление using и само пространство имен.".
Простите, но я не совсем понимаю, куда всё-таки using помещает имена пространства имён? Вот с объявлениями using - куда более яснее. Куда же всё-таки директива using помещает имена??? Я не очень понимаю, что тут хочет донести автор. Хотя, возможно, тут проблемы с переводом.
1
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.10.2016, 20:54
Ответы с готовыми решениями:

Не работает директива
Здравствуйте. Занимаюсь по книге Prata. Использую code::bloocks 17.12... Начал читать про шаблонный класс Array. Странно , но при...

Как работает cin.ignore(), именно в том случае, когда он написан без параметров?
Объясните, пожалуйста, как работает cin.ignore(), именно в том случае, когда написан без параметров заранее спасибо!

Как работает метод Post, как именно он пересылает данные
Всем доброго времени суток. Прошу прощения если я опять ошибся разделом и уже задолбал весь форум своими постами, но обратиться больше...

10
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,808
10.10.2016, 21:13
Цитата Сообщение от csgorulit Посмотреть сообщение
куда всё-таки using помещает имена пространства имён?
В то пространство имен, в котором она (using) написана.
1
192 / 128 / 52
Регистрация: 19.01.2010
Сообщений: 518
10.10.2016, 21:26
Цитата Сообщение от csgorulit Посмотреть сообщение
Применение директивы using равносильно объявлению имен в наименьшей декларативной области, которая содержит объявление using и само пространство имен
Если я правильно понимаю:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using namespace std; //...которая содержит объявление using и само пространство имен
...
void func(int)
{        
}
 
int main()
{
        auto f1 = bind(func, placeholders::_1);
 
//Применение директивы using равносильно объявлению имен в наименьшей декларативной области
        using namespace std::placeholders; 
 
        auto f2 = bind(func, _1);
        //...
}
1
1 / 1 / 0
Регистрация: 07.04.2016
Сообщений: 40
10.10.2016, 22:05  [ТС]
Мда... Что-то я никак не врублюсь... Хотя смысл директивы using понятен.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
10.10.2016, 22:07
Лучший ответ Сообщение было отмечено ValeryS как решение

Решение

Цитата Сообщение от csgorulit Посмотреть сообщение
куда всё-таки using помещает имена пространства имён?
Директива using ничто никуда не помещает. using добавляет пространство в список поиска имён. Т.е. если в текущем пространстве имя не найдено, то оно будет искаться в пространствах, заданных в using

C++
// Ошибка. В глобальном пространстве нет имени "x"
 
namespace aaa
{
  int x;
}
 
int foo (void)
{
  return x;
}
C++
// В глобальном пространстве нет имени "x", но оно есть
// в пространстве "aaa". Этот код отработает
 
namespace aaa
{
  int x;
}
 
using namespace aaa;
 
int foo (void)
{
  return x;
}
При этом надо не забывать, что любое локальное имя всегда перебивает глобальное
3
1 / 1 / 0
Регистрация: 07.04.2016
Сообщений: 40
10.10.2016, 22:09  [ТС]
Спасибо, про это я как раз и не забываю. Просто автор данной книги иногда "выносит мозг" некоторыми своими объяснениями.
0
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
11.10.2016, 00:08
Лучший ответ Сообщение было отмечено csgorulit как решение

Решение

Цитата Сообщение от Evg Посмотреть сообщение
что любое локальное имя всегда перебивает глобальное
Если точнее то поиск имени продолжается до его нахождения, и при нахождении имени поиск прекращается, несмотря на то, нашли ли мы нужное определение, или нет.
Например:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
 
namespace Ns
{
    namespace Ns1
    {
        void f(char a) {std::cout << "char" << std::endl;}
    }
    namespace Ns2
    {
        void f(int a) {std::cout << "int" << std::endl;}
    }
    namespace Ns3
    {
        using namespace ::Ns::Ns1;
        using namespace ::Ns::Ns2;
//      void f(double a) {std::cout << "double" << std::endl;}// А еще расскомментируйте и запустите.
//      int f; // ну и это расскомментируйте потом отдельно.
    }
}
 
int main()
{
    Ns::Ns3::f(10);
    Ns::Ns3::f(char(10));
    return 0;
}
csgorulit, Также в бонус, расскажу что в верхнем коде имя Ns::Ns3::f не является квалифицированным, а вот вложенное имя Ns3::f уже является таковым. Т.е. при поиске определения для Ns::Ns3::f компилятор сначала ищет определение Ns в функции main, и потом поднимается во обрамляющее "пространство имён" и ищет уже в нём, и в нашем верхнем случае находит.
Ведь может быть main выглядит вот так :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
    struct Ns
    {
        struct Ns3
        {
            static void f(float) {std::cout << "float" << std::endl;}
        };
    };
    Ns::Ns3::f(10);
    Ns::Ns3::f(char(10));
    return 0;
}
И в нашем первом случае, только лишь в данном пространстве имен продолжает поиск оставшихся Ns3::f, поскольку они уже являются квалифицированными.
Интересны грабли? Пожалуйста:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
 
namespace Ns
{
    namespace Ns
    {
        namespace Ns1
        {
            struct f
            {
                f(char)
                {
                    std::cout << "я потешный 'баг', найди меня" << std::endl;
                }
            };
        }
    }
    namespace Ns1
    {
        void f(char a) {std::cout << "double" << std::endl;}
    }
    namespace Ns3
    {
        using namespace Ns::Ns1;// неквалифицированное имя - поиск начинается с локальной области.
//      using namespace ::Ns::Ns1;// квалифицированное имя - поиск сразу начинается с глобальной области.
    }
}
 
int main()
{
    Ns::Ns3::f(10);
    Ns::Ns3::f(char(10));
    return 0;
}
Также обратите внимание, что выбор перегрузки функции и другие разбирательства что это за имя, происходят после связывания имени с определением.

Надеюсь это вам будет полезно
3
1 / 1 / 0
Регистрация: 07.04.2016
Сообщений: 40
11.10.2016, 00:21  [ТС]
Спасибо!!!
0
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
11.10.2016, 00:34
Цитата Сообщение от Nosey Посмотреть сообщение
Интересны грабли?
Грабли с поиском имен можно найти не только с using'ом.
Вот, пожалуйста:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
 
struct Test {};
 
 
template<class T> 
void foo(const T &x)
{
    std::cout << "oops..." << std::endl;
}
 
 
void foo(double)
{
    std::cout << "foo(double)" << std::endl;
}
 
 
 
template<class T> 
void bar(const T &x)
{
    foo(x);
}
 
 
void foo(const Test &)
{
    std::cout << "foo(const Test &)" << std::endl;
}
 
 
void foo(int)
{
    std::cout << "foo(int)" << std::endl;
}
 
 
int main()
{   
    bar(Test());//Вызывается перегрузка
    bar(5);//Вызывается шаблонная функция
    bar(5.0);//Вызывается перегрузка
}
http://rextester.com/LBJ71910
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
 
struct Test {};
 
 
template<class T> 
void foo(const T &x)
{
    std::cout << "oops..." << std::endl;
}
 
 
void foo(double)
{
    std::cout << "foo(double)" << std::endl;
}
 
 
 
template<class T> 
void bar(const T &x)
{
    ::foo(x);
}
 
 
void foo(const Test &)
{
    std::cout << "foo(const Test &)" << std::endl;
}
 
 
void foo(int)
{
    std::cout << "foo(int)" << std::endl;
}
 
 
int main()
{   
    bar(Test());//Шаблон
    bar(5);//Шаблон
    bar(5.0);//Перегрузка
}
http://rextester.com/LPMI16787
3
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
11.10.2016, 09:52
Цитата Сообщение от Nosey Посмотреть сообщение
Если точнее то поиск имени продолжается до его нахождения, и при нахождении имени поиск прекращается, несмотря на то, нашли ли мы нужное определение, или нет
Я не знаю тонкостей стандарта, да и мысль твою не совсем понял, что означает "поиск продолжается до нахождения". Для локальных (включая вложенные лексические блоки) и глобальных переменных в том смысле, в каком это было в Си - да, поиск идёт до первого найденного имени. В C++ с учётом using namespace, насколько я вижу из короткого примера, это не так:

C++
namespace aaa
{
  int x;
};
 
int x;
 
using namespace aaa;
 
int foo (void)
{
  return x;
}
Code
$ g++ t.cc -c
t.cc: In function 'int foo()':
t.cc:12:10: error: reference to 'x' is ambiguous
   return x;
          ^
t.cc:6:5: note: candidates are: int x
 int x;
     ^
t.cc:3:7: note:                 int aaa::x
   int x;
       ^
0
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
11.10.2016, 12:08
Evg, Ну да, плохой с меня учитель Я говорил о квалифицированном поиске имени :

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
 
namespace Ns
{
    namespace aaa
    {
        int x = 20;
    }
 
    int x = 10;
 
    using namespace aaa;
}
using namespace Ns;
 
int foo(void)
{
    return ::x; // квалифид нэйм. - будем искать имя включая using'овые неймспейсы рекурсивно.
}
 
int main()
{
    std::cout << foo();
}
Code
1
Hello, world!
А в случае unqualified name lookup все using'и разворачиваются "сразу".
Но предлагаю на этом закончить, а-то спугнём молодую кровь, если молодая кровь еще тут, после увиденного от Croessmah, всяких магий argument dependent lookup -> dependent name.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.10.2016, 12:08
Помогаю со студенческими работами здесь

Как работает функция GetAsyncKeyState, как проверить её результат(именно наименьший бит)
#include &quot;stdafx.h&quot; #include &lt;Windows.h&gt; int _tmain(int argc, _TCHAR* argv) { SHORT s = 0; while(true) ...

Не могу понять алгоритм. Как именно он работает
Не могу понять сам алгоритм. Как именно он считает. Само задание: дано n блоков, какое количество всевозможных лестниц можно из них...

Не работает директива $I
Хочу проверить наличие файла, но паскаль воспримает директиву как комментарий. Что не так? В похожей теме ответ так и никто не дал {$I-} ...

Как именно в методах расширения указать, что переходить нужно именно главный контроллер?
В проекте есть несколько Areas. Маршрутизация нстроена так (для наглядности сократил) public class RouteConfig { ...

Не работает директива omp for
Здравствуйте! Проблема такая, программа создает параллельные потоки и в таком варианте #include &lt;iostream&gt; #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru