Чтобы работало так:
#include ...
#using ...
struct A
{
sometemplate<int> nSomeVal;
sometemplate<std::string> strSomeName;
}
int main()
{
cout << nSomeVal.varname << endl;
cout << strSomeName.varname << endl;
return 0;
}
Выдавало на выходе
nSomeVal
strSomeName
Cпасибо
Или хотя бы так:
#include ...
#using ...
struct A
{
sometemplate<int> nSomeVal;
sometemplate<std::string> strSomeName;
}
int main()
{
A a;
cout << a.nSomeVal.varname << endl;
cout << a.strSomeName.varname << endl;
return 0;
}
И на выходе было бы то же, что и впредыдущем посте
Здравствуйте, Аноним, Вы писали:
struct A
{
sometemplate<int> nSomeVal;
sometemplate<std::string> strSomeName;
}
Так -- никак. Можно только
SOMEMACRO( type, name );
Либо прикрутить внешний скрипт дополнительной фазой сборки, тогда можно и шаблонами сделать...
Только зачем тебе имена переменных? Для отладки? Может, можно проще?
Здравствуйте, <Аноним>, Вы писали:
Эта штука называется рефлексией. Изначально, рефлексии в С++ нет. Только ручками...
Может быть, что-то такое можно сделать на макросах.
#define NAMED_PROPERTY(type,var) .....
struct A
{
NAMED_PROPERTY(int, x);
NAMED_PROPERTY(string, y);
A() : x(123) {}
};
int main()
{
A a;
cout << a.x.name << " = " << a.x.value << endl;
cout << a.y.name << " = " << a.y.value << endl;
}
Если такой дизайн тебя устраивает, то вот
// немножко макропрограммирования (можно стырить из boost preprocessor)
#define PP_CAT(a,b) PP_CAT_(a,b)
#define PP_CAT_(a,b) a##b
#define PP_STR(s) PP_STR_(s)
#define PP_STR_(s) #s
#define NAMED_PROPERTY(Type,Var) \
struct PP_CAT(_tag_,Var) \
{ \
const char* const name; \
type value; \
PP_CAT(_tag_,Var) () : name(PP_STR(Var)) {} \
template<class T> PP_CAT(_tag_,Var) (const T& src) : name(PP_STR(Var)), value(src) {} \
} var; \
//endmacro
Оно развернётся в
struct A
{
struct _tag_x
{
const char* const name;
int value;
_tag_x() : name("x") {}
template<class T> _tag_x(const T& src) : name("x"), value(src) {}
} x;;
struct _tag_y
{
const char* const name;
string value;
_tag_y() : name("y") {}
template<class T> _tag_y(const T& src) : name("y"), value(src) {}
} y;;
A() : x(123) {}
};
... << RSDN@Home 1.2.0 alpha rev. 655>>
Здравствуйте, quodum, Вы писали:
Q>Так -- никак. Можно только
Q>Q> SOMEMACRO( type, name );
Q>
Q>Либо прикрутить внешний скрипт дополнительной фазой сборки, тогда можно и шаблонами сделать...
Лучше всего без скриптов, если можно прикрутить макро к обьявлению переменной класса, чтобы он вызывал при ее объявлении конструктор этой переменной. И лучше всего это сделать именно для шаблонных классов. Так можно?
Q>Только зачем тебе имена переменных? Для отладки? Может, можно проще?
Для работы с реестром и *.ini. Можно и проще, но тогда нужно имя ключа инициализировать дополнительно, то есть если реализовать инициализацию имени при объявлении, то для реестра и *.ini нужно писать кода примерно в 3 раза меньше.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, <Аноним>, Вы писали:
К>Эта штука называется рефлексией. Изначально, рефлексии в С++ нет. Только ручками...
К>Может быть, что-то такое можно сделать на макросах.
К>К>#define NAMED_PROPERTY(type,var) .....
К>struct A
К>{
К> NAMED_PROPERTY(int, x);
К> NAMED_PROPERTY(string, y);
К> A() : x(123) {}
К>};
К>int main()
К>{
К> A a;
К> cout << a.x.name << " = " << a.x.value << endl;
К> cout << a.y.name << " = " << a.y.value << endl;
К>}
К>
К>Если такой дизайн тебя устраивает, то вот
К>К>// немножко макропрограммирования (можно стырить из boost preprocessor)
К>#define PP_CAT(a,b) PP_CAT_(a,b)
К>#define PP_CAT_(a,b) a##b
К>#define PP_STR(s) PP_STR_(s)
К>#define PP_STR_(s) #s
К>#define NAMED_PROPERTY(Type,Var) \
К> struct PP_CAT(_tag_,Var) \
К> { \
К> const char* const name; \
К> type value; \
К> PP_CAT(_tag_,Var) () : name(PP_STR(Var)) {} \
К> template<class T> PP_CAT(_tag_,Var) (const T& src) : name(PP_STR(Var)), value(src) {} \
К> } var; \
К> //endmacro
К>
К>Оно развернётся в
К>К>struct A
К>{
К> struct _tag_x
К> {
К> const char* const name;
К> int value;
К> _tag_x() : name("x") {}
К> template<class T> _tag_x(const T& src) : name("x"), value(src) {}
К> } x;;
К> struct _tag_y
К> {
К> const char* const name;
К> string value;
К> _tag_y() : name("y") {}
К> template<class T> _tag_y(const T& src) : name("y"), value(src) {}
К> } y;;
К> A() : x(123) {}
К>};
К>
Да, это примерно то, что нужно. Спасибо.
А>Да, это примерно то, что нужно. Спасибо.
Вот только оверквотить не стоило
А ещё я подумал: незачем каждому экземпляру тащить копию указателя. Да и с копированием станет попроще...
#define NAMED_PROPERTY(Type,Var) \
struct PP_CAT(_tag_,Var) \
{ \
static const char* name() { return PP_STR(Var); } \
Var value; \
PP_CAT(_tag_,Var) () {} \
template<class T> PP_CAT(_tag_,Var) (const T& src) : value(src) {} \
}; \
//endmacro
.....
cout << a.x.name() << " = " << a.x.value << endl;
... << RSDN@Home 1.2.0 alpha rev. 655>>
Здравствуйте, Кодт, Вы писали:
К>Вот только оверквотить не стоило
К>А ещё я подумал: незачем каждому экземпляру тащить копию указателя. Да и с копированием станет попроще...
Возможно да, но вобще — то задача сложнее, это только ее часть, так что эти макро все равно нужно будет существенно переделывать. А принцип уже понятен.