У меня есть хорошо сформированный код, который выглядит так:
NAMESPACE_BEGIN(Foo)
inline void test() {
string s = xxx;
}
NAMESPACE_END(Foo)
Итак, есть ли какие-либо переносные трюки с помощью макроса NAMESPACE_BEGIN()
чтобы получить имя пространства имен "Foo" в test()
?
Я думаю о чем-то подобном, но это, несомненно, вызовет переопределение символов:
#define NAMESPACE_BEGIN(x) \
namespace x { \
inline const char *_curNamespace() { \
return #x; \
}
#define NAMESPACE_END(x) \
}
Там также обходное решение выглядит так, но это не очень удобно
#define NAMESPACE_NAME Foo
// using a header file so that we can use #ifdef guard
#include "MyNamespaceBegin.h"
...
#include "MyNamespaceEnd.h"
EDIT:
-
Зачем мне это нужно:
Я использую большую часть макроса для генерации кодов для достижения некоторой логики динамического отражения (да, а не статического отражения шаблона), все в порядке в пределах класса, используя статическую функцию-член, но не работает для пространств имен
-
Почему бы не вручную объявить имя getter один раз:
Я хочу что-то вроде этого:
// the global default version const char *_curNamespace() {return "";} namespace X { // the local namespace version const char *_curNamespace() {return "X";} // some verbose reflection register code ... registerSomething(_curNamespace()); ... }
Конечно, весь код регистрового регистра должен быть сгенерирован макросом
И пользователь уровня приложения не должен заботиться о
_curNamespace()
, поэтому я хочу упростить использование пользователя, используя произвольный макросNAMESPACE_BEGIN(xxx)
в любом случае -
Если вам все еще интересно, что я делаю, проверьте это: https://github.com/ZFFramework/ZFFramework
Я использую много трюков для достижения полностью динамического отражения в чистом C++, чтобы достичь некоторых из моих причудливых мыслей, на данный момент этот проект просто для удовольствия, я не знаю, имеет ли он практичность
EDIT2:
На данный момент я считаю, что наилучшим обходным решением должно быть следующее:
#define NAMESPACE_BEGIN(ns) \
namespace ns { \
extern const char *__curNS();
#define NAMESPACE_END(ns) \
}
#define NAMESPACE_REG(ns) \
const char *__curNS() {return #ns;}
- пользователям уровня приложения по-прежнему нужно только заботиться о
NAMESPACE_BEGIN
-
NAMESPACE_REG
должен быть объявлен ровно один раз, в исходном файле- если нет, то будет отображаться неопределенный символ
- если не один раз, дублированный символ произойдет
- хотя это раздражает, а иногда вам нужен дополнительный исходный файл для хранения
NAMESPACE_REG
, строгое правило должно помешать пользователю забыть уродливое обходное решение