Авто-регистрация членов класса в самом классе.
От: MaxEd Россия http://www.dhost.info/msiu/
Дата: 26.01.11 07:18
Оценка:
Хочется такую штуку, чтобы можно было написать примерно следующее:

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, но как лучше — не соображу.
Re: Авто-регистрация членов класса в самом классе.
От: remark Россия http://www.1024cores.net/
Дата: 26.01.11 07:45
Оценка:
Здравствуйте, 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



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Авто-регистрация членов класса в самом классе.
От: jerry_ru  
Дата: 26.01.11 20:33
Оценка:
Здравствуйте, 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 работающий при компиляции а не в рантайме...
Re[2]: Авто-регистрация членов класса в самом классе.
От: MaxEd Россия http://www.dhost.info/msiu/
Дата: 27.01.11 06:46
Оценка:
Здравствуйте, 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.
Re[2]: Авто-регистрация членов класса в самом классе.
От: MaxEd Россия http://www.dhost.info/msiu/
Дата: 27.01.11 06:47
Оценка:
Здравствуйте, 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:


Хе, значит, я всё-таки шёл относительно верным путём, судя по второй статье :) Спасибо, ссылка информативная.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.