Хочется такую штуку, чтобы можно было написать примерно следующее:
class SomeClass : MemberHolder
{
TMember<int> m1;
TMember<std::string> m2;
TMember<SomeOtherClass> m3;
public:
void SomeFunc()
{
MemberList & l = MemberHolder::GetMemberList();
// Далее, допустим, итерация по l и какое-нибудь действие
}
};
При этом, хочется, чтобы НЕ НАДО было упомянать TMember'ов в конструкторе, т.е. не подходят решения вида
class SomeClass : MemberHolder
{
TMember<int> m1;
TMember<std::string> m2;
TMember<SomeOtherClass> m3;
public:
SomeClass()
: m1( this )
, m2( this )
, m3( this )
};
Подскажите, есть ли хороший способ так сделать в текущем стандарте, или при помощи новых фич C++0x? Я пока изобрёл мега-извращённый способ, который страдает полным отсутствием thread-safety и наличием неявных, но очень опасных ограничений:
class TMember;
class BaseHolder
{
public:
void RegisterMember( TMember *m ) {...} // добавляем мембера, например, в список
}
class RegistrationHelper
{
BaseHolder *m_pCurrent;
public:
void SetCurrentHolder( BaseHolder *pCurrent ) { m_pCurrent = pCurrent; }
void RegisterMember( TMember *m ) { if ( m_pCurrent ) m_pCurrent->RegisterMember( m ); }
};
template<typename T, RegistrationHelper *helper>
class TMember
{
T m_value;
public:
TMember()
{
helper->Register( this );
}
};
class MemberContainer : public BaseHolder
{
protected:
static RegistrationHelper helper; // Где-то в каком-то cpp его надо инициализировать
public:
MemberContainer()
{
helper.SetCurrentHolder( this );
}
};
class SomeClass : MemberContainer
{
TMember< int, &helper > m_member1;
TMember< WhatEver, &helper > m_member2;
public:
SomeClass(){}
};
Подозреваю, что сей метод достоин TheDailyWTF, но как лучше — не соображу.
Здравствуйте, MaxEd, Вы писали:
ME>Хочется такую штуку, чтобы можно было написать примерно следующее:
ME>Подозреваю, что сей метод достоин TheDailyWTF, но как лучше — не соображу.
Ничего хорошего пока не получается. Как ни крути получается WTF.
Посмотри вот это (основано на паттерне CRMO — Curiously Recurring Memory Overwriting):
http://rsdn.ru/forum/cpp/2092771.1.aspxАвтор: remark
Дата: 04.09.06
и вот это:
http://rsdn.ru/forum/cpp/2265191.1.aspxАвтор: remark
Дата: 14.12.06
Здравствуйте, MaxEd, Вы писали:
ME>Хочется такую штуку, чтобы можно было написать примерно следующее:
ME>ME>class SomeClass : MemberHolder
ME>{
ME> TMember<int> m1;
ME> TMember<std::string> m2;
ME> TMember<SomeOtherClass> m3;
ME>public:
ME> void SomeFunc()
ME> {
ME> MemberList & l = MemberHolder::GetMemberList();
ME> // Далее, допустим, итерация по l и какое-нибудь действие
ME> }
ME>};
ME>
ME>При этом, хочется, чтобы НЕ НАДО было упомянать TMember'ов в конструкторе, т.е. не подходят решения вида
Не совсем понял вопрос, но может подойдет так:
struct action
{
template<typename T>
void operator()(T& t) const
{}
void operator()(int& t) const
{std::cerr<<"this is int!"<<std::endl;}
void operator()(std::string& t) const
{std::cerr<<"this is string!"<<std::endl;}
};
class SomeClass{
boost::fusion::list<int, std::string, SomeOtherCLass> members;
public:
void SomeFunc()
{
boost::fustion::for_each(members, action());
}
};
есть возможность использовать fusion::map, или for_each работающий при компиляции а не в рантайме...
Здравствуйте, jerry_ru, Вы писали:
_>Не совсем понял вопрос, но может подойдет так:
_>
_>struct action
_>{
_> template<typename T>
_> void operator()(T& t) const
_> {}
_> void operator()(int& t) const
_> {std::cerr<<"this is int!"<<std::endl;}
_> void operator()(std::string& t) const
_> {std::cerr<<"this is string!"<<std::endl;}
_>};
_>class SomeClass{
_> boost::fusion::list<int, std::string, SomeOtherCLass> members;
_>public:
_> void SomeFunc()
_> {
_> boost::fustion::for_each(members, action());
_> }
_>};
_>
_>есть возможность использовать fusion::map, или for_each работающий при компиляции а не в рантайме...
Это хорошо, конечно, но главный вопрос не в том, где хранить и как пробегаться по списку членов, а как они, собственно, попадут в members.
Здравствуйте, remark, Вы писали:
R>Ничего хорошего пока не получается. Как ни крути получается WTF.
R>Посмотри вот это (основано на паттерне CRMO — Curiously Recurring Memory Overwriting):
R>http://rsdn.ru/forum/cpp/2092771.1.aspxАвтор: remark
Дата: 04.09.06
R>и вот это:
R>http://rsdn.ru/forum/cpp/2265191.1.aspxАвтор: remark
Дата: 14.12.06
R> :beer:
Хе, значит, я всё-таки шёл относительно верным путём, судя по второй статье :) Спасибо, ссылка информативная.