Я видел оба подхода в коде. Не могли бы вы объяснить, в чем разница между ними? Как я думаю, это связано с тем, как поиск пространства имен выполняется с помощью C++, можете ли вы предоставить некоторую информацию об этом, или, возможно, ссылку на хороший документ? Благодарю.В чем разница между написанием «:: namespace :: identifier» и «namespace :: identifier»?
ответ
Это действительно не имеет значения, по крайней мере, не большую часть времени.
В формате ::identifier1::identifier2
, предыдущая двоеточие говорит, чтобы посмотреть глобальную область для identifier1
, а затем искать identifier2
в этой области.
В формате identifier1::identifier2
мы вместо этого рассмотрим текущий scope for identifier1
. Если мы его не найдем, будет поиск объекта родителя, и так далее, пока мы его не найдем. Затем мы ищем identifier2
в пределах того объема, который мы только что нашли.
В случае, если вы уже находитесь в глобальном масштабе, это не имеет значения. Но эта история меняется, когда вы работаете в пространстве имен или классах, в которых есть другие пространства имен или классы.
Отлично, спасибо. –
Пример:
#include <cstdio>
namespace x {
const int i = 1;
}
namespace y {
namespace x {
const int i = 2;
}
void func()
{
std::printf("x::i = %d\n", x::i);
std::printf("::x::i = %d\n", ::x::i);
}
}
int main()
{
y::func();
return 0;
}
Выход:
x::i = 2 ::x::i = 1
Объяснение:
Когда вы ссылаетесь на язя ntifier, как
x::i
, используемое определение является «самым близким»x::i
. Внутри::y::func
определение::y::x::i
ближе, чем определение::x::i
. Напротив, нет такой функции::y::std::printf
, поэтому вместо этого используется::std::printf
.При обращении к идентификатору, как
::x::i
, нет никакой возможности двусмысленности: он ищет пространство имена верхнего уровня с именемx
, затем находитi
внутри.
Таким образом, используя ::
в начале позволяет пишется полное имя глобальной что-то. Это также позволяет различать локальные и глобальные переменные.
Пример 2:
#include <cstdio>
const int x = 5;
int main()
{
const int x = 7;
std::printf("x = %d\n", x);
std::printf("::x = %d\n", ::x);
return 0;
}
Выход:
x = 7 ::x = 5
Почему «std: : printf "работает тогда, внутри пространства имен" y "? В пространстве имен «y» нет пространства имен «std». Не могли бы вы также объяснить этот бит? –
@drandrestor: Это похоже на переменную область видимости - если компилятор не находит имя на текущем уровне, он «выскакивает» на один уровень и ищет его там. В этом случае пространство имен 'std' не существует в' y', поэтому компилятор затем проверяет глобальное пространство имен и находит его там. –
Ха, 9 против 1 и 1 приняты ... –
- 1. В чем разница между NameNode и NameSpace
- 2. Разница между «namespace» и «use»
- 3. В чем разница между `объявить namespace` и` объявить module`
- 4. В чем преимущество использования :: namespace :: something over namespace :: something?
- 5. Multipart Identifier и функции
- 6. CIN, COUT Undelcared Identifier
- 7. Bundle Identifier
- 8. В SNMP MIB, в чем разница между «MODULE-IDENTITY» и «OBJECT IDENTIFIER»?
- 9. C++ class inheritance, identifier undefined
- 10. C2061 'string': uneclared identifier
- 11. Identifier ожидается в Const
- 12. Hibernate custom identifier generattion
- 13. В чем разница между именем класса как MyClass и namespace \ Myclass в PHP?
- 14. В чем разница между this-> variable и namespace :: class :: variable в C++?
- 15. sanitize и namespace
- 16. Ключевое слово Namespace в TypeScript
- 17. namespace и xpath
- 18. currentFrame identifier [AS3]
- 19. ASP.NET Namespace
- 20. разрешения Identifier и простое задание
- 21. Casting Namespace
- 22. Redis namespace
- 23. namescript namespace
- 24. jQuery.data() namespace
- 25. C# namespace alias - в чем смысл?
- 26. App.configuration namespace
- 27. ViewModel NameSpace
- 28. Undeeclared namespace
- 29. JsDoc Namespace
- 30. AssertionFailure: «null identifier» - FluentNH + SQLServerCE
Это как разница между '/ usr/bin/rm' и' usr/bin/rm'; или между 'Windows \ calc.exe' и' C: \ Windows \ calc.exe'. –
@KerrekSB хорошая аналогия –
Не правда ли? Если я объявляю пространство имен и использую идентификатор «std :: cout», он все равно будет работать, однако в моем собственном пространстве имен не существует «std» пространства имен. –