Я читал о using
-директивах на cppreference.com и у них был какой-то код, я не мог понять предпочтения порядка для поиска имени.
Я прочитал о транзитивном свойстве using
-директив в параграфе 3< /a>, unqualified_lookup#область пространства имен и scope#namespace_scope. Я также пробовал искать на некоторых других сайтах.
Если есть еще какие-то документы, которые, по вашему мнению, мне следует прочитать, предложите их.
Их код следующий:
Не тратьте слишком много времени на чтение этого кода, потому что ниже я расскажу о своей адаптированной версии.
namespace A {
int i;
}
namespace B {
int i;
int j;
namespace C {
namespace D {
using namespace A; // all names from A injected into global namespace
int j;
int k;
int a = i; // i is B::i, because A::i is hidden by B::i
}
using namespace D; // names from D are injected into C
// names from A are injected into global namespace
int k = 89; // OK to declare name identical to one introduced by a using
int l = k; // ambiguous: C::k or D::k
int m = i; // ok: B::i hides A::i
int n = j; // ok: D::j hides B::j
}
}
Я адаптировал их код для вывода на печать:
Я помещаю пронумерованные вопросы в качестве комментариев к тем, которые я не понимаю. Вам не нужно отвечать на все вопросы, если вы можете объяснить порядок или поиск имени, и вы думаете, что я сам могу ответить на остальные вопросы.
Если мои вопросы слишком запутаны, не могли бы вы вместо этого попытаться объяснить поиск имен переменных в приведенном выше коде cppreference?
#include <iostream>
using namespace std;
namespace A {
int b = 0;
int i = 1;
}
namespace B {
int b = 2;
int i = 3;
int j = 4;
namespace C {
namespace D {
// 1) Why does cppreference say A is injected into `global`
// and not `D` namespace?
using namespace A; // all names from A injected into global namespace
int j = 5;
int k = 6;
int a = i; // i is B::i, because A::i is hidden by B::i
}
using namespace D; // names from D are injected into C
// 2) Why does cppreference say A is injected into `global` and
// not `C` namespace?
// names from A are injected into global namespace
int k = 7; // OK to declare name identical to one introduced by a using
// 3) What makes this ambiguous and not "one hides the other"?
// int l = k; // ambiguous: C::k or D::k
int m = i; // ok: B::i hides A::i
int n = j; // ok: D::j hides B::j
int c = b;
}
}
int main()
{
cout << "A::b " << A::b << endl; // prints "A::b 0"
cout << "A::i " << A::i << endl; // prints "A::i 1"
cout << endl;
cout << "B::b " << B::b << endl; // prints "B::b 2"
cout << "B::i " << B::i << endl; // prints "B::i 3"
cout << "B::j " << B::j << endl; // prints "B::j 4"
cout << endl;
cout << "B::C::a " << B::C::a << endl; // prints "B::C::a 3"
cout << "B::C::b " << B::C::b << endl; // prints "B::C::b 0"
cout << "B::C::c " << B::C::c << endl; // prints "B::C::c 2"
cout << "B::C::i " << B::C::i << endl; // prints "B::C::i 1"
cout << "B::C::j " << B::C::j << endl; // prints "B::C::j 5"
cout << "B::C::k " << B::C::k << endl; // prints "B::C::k 7"
cout << "B::C::m " << B::C::m << endl; // prints "B::C::m 3"
cout << "B::C::n " << B::C::n << endl; // prints "B::C::n 5"
cout << endl;
cout << "B::C::D::a " << B::C::D::a << endl; // prints "B::C::D::a 3"
cout << "B::C::D::b " << B::C::D::b << endl; // prints "B::C::D::b 0"
cout << "B::C::D::i " << B::C::D::i << endl; // prints "B::C::D::i 1"
cout << "B::C::D::j " << B::C::D::j << endl; // prints "B::C::D::j 5"
cout << "B::C::D::k " << B::C::D::k << endl; // prints "B::C::D::k 6"
cout << endl;
return 0;
}
Полный вывод:
Я помещаю пронумерованные вопросы в качестве комментариев к тем, которые я не понимаю.
Я предлагаю вам открыть приведенный выше код рядом, чтобы вы могли видеть, на что я ссылаюсь. Я сохранил строки ‹ 80 символов.
A::b 0
A::i 1
B::b 2
B::i 3
B::j 4
B::C::a 3 // 4) cppreference says A::i == 1 is hidden by B::i == 3
// so this is == 3 and not 1.
// Why doesn't A::i hide B::i?
// Doesn't the `using namespace A` make A::i closer in scope
// than B::i?
// Why does this go up the parent blocks C->B->B::i == 3 and
// not up the namespaces C->D->A->A::i == 1?
B::C::b 0 // 5) This is == A::b == 0. This goes through the
// `using namespace D` which contains `using namespace A`.
// Why does this go up the namespaces C->D->A->A::b == 0 and
// not the parent blocks to C->B->B::b == 2 like in question 4?
B::C::c 2 // 6) This is == B::b == 2 (go up blocks C->B->B::b == 2).
// Why is it not == B::C:b == 0
// (go up namespaces C->D->A->A::b == 0 like in question 5)
// from the assignment `int c = b`?
// I'm guessing because name lookup for b
// inside the namespace body is different than the B::C::b lookup
// outside of the namespace body.
B::C::i 1 // 7) Compared to question 9 below, i is assigned to m but 1 != 3.
// I think this is similar to question 6 where name lookup
// outside of the namespace body is different than inside.
// I'm not sure why this goes up namespaces C->D->A->A::i == 1
// and not blocks C->B->B::i == 3.
B::C::j 5 // 8) Why does it go up namespaces C->D->D::j and not blocks
// C->B->B::j == 4?
B::C::k
B::C::m 3 // 9) cppreference says B::i hides A::i so this is == B::i == 3
// Why does this go up blocks C->B->B::i == 3 and not namespaces
// C->D->A->A::i == 1?
// Actually, I guess questions 9 and 7 is the same situation as
// questions 6 and 5, respectively. Where m and i corresponds
// with c and b, respectively.
B::C::n 5 // 10) cppreference says D::j hides B::j so this is == D::j == 5
// Why does this go up namespaces C->D->D::j == 5 and not
// blocks C->B->B::j == 4? The only difference I see between
// question 9 and 10 is that for question 9, i isn't declared
// within D like j is.
B::C::D::a 3 // 11) cppreference says A::i is hidden by B::i so
// this == B::i == 3. Why does this go up the blocks
// D->C->B->B::i == 3 instead of the
// namespaces D->A->A::i == 1?
// This goes up the blocks like question 9 but not
// up the namespaces like question 10.
B::C::D::b 0 // 12) This probably goes up the namespaces D->A->A::b == 0 and not
// blocks D->C->B->B::b == 2 because b is accessed
// outside the namespace body similar to questions 5, 7, and 8.
// Access inside the namespace body would be question 11 since
// the reference to i was captured inside a.
B::C::D::i 1 // 13) I think this is similar (~) to question 12 ~ 5, 7, and 8
// where it goes up namespaces D->A->A::i == 1 instead
// of blocks D->C->B->B::i == 3 because i is accessed outside
// of the namespace body.
B::C::D::j 5
B::C::D::k 6
Список вопросов, появившихся выше:
- Почему cppreference говорит, что A вводится в пространство имен
global
, а неD
? - Почему cppreference говорит, что A вводится в пространство имен
global
, а неC
? - Что делает это двусмысленным, а не "одно скрывает другое"?
- cppreference говорит, что A::i == 1 скрыто B::i == 3, поэтому это == 3, а не 0. Почему A::i не скрывает B::i? Разве
using namespace A
не делает A::i ближе по объему, чем B::i? Почему это поднимается вверх по родительским блокам C->B->B::i == 1, а не вверх по пространствам имен C->D->A->A::i == 3? - Это == A::b == 0. Это проходит через
using namespace D
, который содержитusing namespace A
. Почему это поднимается вверх по пространствам имен C->D->A->A::b == 0, а не по родительским блокам до C->B->B::b == 2, как в вопросе 4? - Это == B::b == 2. Почему это не == B::C:b == 0 из присваивания
int c = b
? Я предполагаю, что поиск имени для b внутри тела пространства имен отличается от поиска B::C::b вне тела пространства имен. - По сравнению с вопросом 9 ниже, i присвоено m, но 1 != 3. Я думаю, что это похоже на вопрос 6, где поиск имени вне тела пространства имен отличается от поиска внутри. Я не уверен, почему это поднимается вверх по пространствам имен C->D->A->A::i == 1, а не блокирует C->B->B::i == 3.
- Почему он поднимается вверх по пространствам имен C->D->D::j, а не блокирует C->B->B::j == 4?
- cppreference говорит, что B::i скрывает A::i, так что это == B::i == 3 Почему это идет вверх по блокам C->B->B::i == 3 а не пространствам имен C->D- >А->А::i == 1? На самом деле, я думаю, вопросы 9 и 7 аналогичны вопросам 6 и 5 соответственно. Где m и i соответствуют c и b соответственно.
- cppreference говорит, что D::j скрывает B::j, так что это == D::j == 5 Почему это поднимается вверх по пространствам имен C->D->D::j == 5, а не блокирует C->B- >B::j == 4? Единственная разница, которую я вижу между вопросом 9 и 10, заключается в том, что для вопроса 9 я не объявлен в D, как j.
- cppreference говорит, что A::i скрыт B::i, поэтому это == B::i == 3. Почему это идет вверх по блокам D->C->B->B::i == 3 вместо пространства имен D->A->A::i == 1? Это идет вверх по блокам, как вопрос 9, но не вверх по пространствам имен, как вопрос 10.
- Это, вероятно, поднимается вверх по пространствам имен D->A->A::b == 0, а не блокирует D->C->B->B::b == 2, потому что доступ к b осуществляется вне тела пространства имен, аналогично вопросам 5. , 7 и 8. Доступ внутри тела пространства имен будет вопросом 11, поскольку ссылка на i была захвачена внутри a.
- Я думаю, что это похоже (~) на вопросы 12 ~ 5, 7 и 8, где поднимаются пространства имен D->A->A::i == 1 вместо блоков D->C->B->B: :i == 3, потому что доступ к i осуществляется за пределами тела пространства имен.
using namespace
в пространстве имен вряд ли является хорошей идеей. - person user7860670   schedule 25.02.2018using namespace
, чтобы увидеть, как это работает. Потом я увидел этот пример и не мог уложиться в голове. Код не предназначен быть чем-то полезным, и я знаю, что это беспорядок. Это только в образовательных целях. - person dosentmatter   schedule 25.02.2018