К моему удивлению, когда функция объявлена в том же пространстве имен, что и переменная, функция может получить доступ к этой переменной без уточнения.
// file qqq.cpp
namespace aaa {
void f();
int x;
}
void aaa::f() {
aaa::x; // 0. INTENDED ACCESS to x in namespace aaa (also works)
x; // 1. SURPRISE: x can be accessed without aaa:: qualification
bool x; // 2. SURPRISE: given (1) why is it allowed to redefine x?
}
вопрос:
A) естьЛюбой способ обеспечить, чтобы все объекты в пространстве имен были слепыми по отношению к другим составляющим, и требовать доступа всегда через ::?
B), если нет, какова была бы правильная практика кодирования для получения желаемого поведения?
C) в противном случае альтернативным решением было бы разделить каждое пространство имен на 2, одно для функций и другое для переменных, таких как f_aaa и v_aaa.но это кажется довольно неуклюжим и уродливым в практическом использовании, например.void f_sqlite :: myfun () {v_sqlite :: myvar;} вместо просто void sqlite :: myfun () {sqlite :: myvar;}
edit 1: контекст, «проблема», которую я пытаюсь решить:
рефакторинг нескольких тысяч строк кода, пространства имен считались подходящими для объединения связанных элементов, например.пространство имен sqlite для служебных функций и переменных sqlite, используемых в базе кода.принудительный доступ через :: был бы отличным способом повышения ясности и избежания конфликтов имен и сокрытия.отдельные пространства имен для «одного пакета» победили бы цель.классы не кажутся концептуально подходящими.
edit 2:
D) возможно ли получить ПРЕДУПРЕЖДЕНИЕ (включить флаг компилятора), чтобы сигнализировать, когда функция в пространстве имен aaa обращается к переменной в пространстве имен aaaбез квалификации?
edit 3:
Я думаю, что я все равно буду использовать «отдельные пространства имен», но с помощью вложенных пространств имен
// file qqq.cpp
namespace aaa::f { // namespace for functions
void f();
void g();
}
namespace aaa::v { // namespace for variables
int x;
}
// definition of function f inside namespace aaa::f
void aaa::f::f() {
aaa::v::x; // only way of accessing x in aaa::v (good) (ugly)
x; // compiler error (good)
bool x; // normal scope hiding (good)
g(); // works: ARGH! would like to force qualifying with aaa::f::
}
все еще довольно уродливо, хотя,а также!функции могут по-прежнему вызывать друг друга без оговорок, объекты могут по-прежнему вызывать / ссылаться друг на друга без определения.было бы неплохо просто иметь возможность использовать некоторый «принудительный квалификатор» (например, «приватный») для всех или некоторых элементов внутри пространства имен.