boost::bind insider information

See russian translation below:

Two years ago, I was thinking about understanding "boost::bind" in depth. I created my own boost::bind (at least part of full boost::bind).
Old solution was a mess of a lot of template classes with templates methods.

But on current moment Alexandresku gave me interesting thought about local-classes. New solution decrease amount of code at least at 10 times.
See new solution below.


Где то два года назад я задумался как сделать свой велосипед и изобрести boost::bind (хотя бы частичную его реализацию).

Тогда я намусолил несколько наследований от базовых классов через обёртку из шаблонного класса и шаблонной функции его создающего...

Взявшись таки основательно за Александреску, на 50-ой странице нашёл то, что делает bind таким простым и красивым.

Ну и ещё восхищает красотой и осмысленностью локальных классов:


class thread
{
public:
 virtual void run() = 0;
};

template< class cl, class parameter >
thread* bind( void (cl::*m)(void) , parameter p )
{
 typedef void (cl::*mmethod)(void);

 class thread_r : public thread
 {
  mmethod m_;
  parameter p_;
 public:
  explicit thread_r( mmethod m , parameter p )
   : m_( m )
   , p_( p )
  {
  }
  virtual void run()
  {
   (*p_.*m_)();
  }
 };
 return new thread_r( m, p );
}

//
class A
{
public:
 void method()
 {
 }
};

int main(const int argc, const char* argv[])
{
 A a;
 thread* th = bind( &A::method, &a );
 th->run(); 
 delete th;
 return 0;
}

CMake with Qt

See russian translation below:

Qt with CMake is simple, if you know some features.
I had have some experienvce with Qt, and Qt was really cool.
Qt is cross-platform, open source. That's enought to me.

I had tried to use "installation" version for windows but default namespace is - no namespace, and i don't like it, so I preffer to compile.
I have a lot of problems, when I try to compile sources from installation version.

But just download source version (http://download.qt.nokia.com/qt/source/qt-everywhere-opensource-src-4.7.4.tar.gz) and compilation will not fail (allmost).

Sorry for win32-msvc2005 but this is a conditions for my build system right now.

So build parameters:
configure -platform win32-msvc2005 -debug-and-release -opensource 
    -stl -rtti -qtnamespace gui <y
I tried to use "-static" but sqlite driver had fail to compile.

Well compilation process is not really hard one. Next task to include this library into the project with CMake.

Zero step is to add to system variable PATH, path to qmake binary file, I do such thing into bat script:
set QT_ROOT=D:\usr\qt-everywhere-opensource-src-4.7.4
set PATH=%PATH%;%QT_ROOT%\bin

1) You should add next to find qt and add qt utilities into build system:
 find_package(Qt4 ${SEARCH_PARAMETERS} COMPONENTS QtCore QtGui QtMain)
    include( ${QT_USE_FILE} )
    add_definitions(${QT_DEFINITIONS})
2) Creating special qt namespace for compilation:
    add_definitions( -DQT_NAMESPACE=gui )
3) Finding all necessary files on filesystem:
    file(GLOB ${PROJECT_NAME}_SOURCES *.cpp)
    file(GLOB ${PROJECT_NAME}_HEADERS *.h)
    file(GLOB ${PROJECT_NAME}_FORMS *.ui)
    file(GLOB ${PROJECT_NAME}_RESOURCES *.qrc)
    file(GLOB ${PROJECT_NAME}_SOURCE_LIST ${${PROJECT_NAME}_SOURCES} ${${PROJECT_NAME}_HEADERS} ${${PROJECT_NAME}_FORMS} ${${PROJECT_NAME}_RESOURCES} )
4) Using 'moc' and resource processor:
    QT4_WRAP_CPP(${PROJECT_NAME}_HEADERS_MOC ${${PROJECT_NAME}_HEADERS} )
    QT4_WRAP_UI(${PROJECT_NAME}_FORMS_HEADERS ${${PROJECT_NAME}_FORMS})
    QT4_ADD_RESOURCES(${PROJECT_NAME}_RESOURCES_RCC ${${PROJECT_NAME}_RESOURCES})
5) Including generated headers:
    include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
6) Linking:
    add_executable( ${PROJECT_NAME} ${${PROJECT_NAME}_SOURCE_LIST} ${${PROJECT_NAME}_HEADERS_MOC} ${${PROJECT_NAME}_FORMS_HEADERS} ${${PROJECT_NAME}_RESOURCES_RCC} )
    target_link_libraries( ${PROJECT_NAME} ${QT_LIBRARIES} )

That's all, as you can understand it is not so hard. Let's summarise:
find_package(Qt4 ${SEARCH_PARAMETERS} COMPONENTS QtCore QtGui QtMain)
include( ${QT_USE_FILE} )
add_definitions(${QT_DEFINITIONS})
add_definitions( -DQT_NAMESPACE=gui )

file(GLOB ${PROJECT_NAME}_SOURCES *.cpp)
file(GLOB ${PROJECT_NAME}_HEADERS *.h)
file(GLOB ${PROJECT_NAME}_FORMS *.ui)
file(GLOB ${PROJECT_NAME}_RESOURCES *.qrc)
file(GLOB ${PROJECT_NAME}_SOURCE_LIST ${${PROJECT_NAME}_SOURCES} ${${PROJECT_NAME}_HEADERS} ${${PROJECT_NAME}_FORMS} ${${PROJECT_NAME}_RESOURCES} )

QT4_WRAP_CPP(${PROJECT_NAME}_HEADERS_MOC ${${PROJECT_NAME}_HEADERS} )
QT4_WRAP_UI(${PROJECT_NAME}_FORMS_HEADERS ${${PROJECT_NAME}_FORMS})
QT4_ADD_RESOURCES(${PROJECT_NAME}_RESOURCES_RCC ${${PROJECT_NAME}_RESOURCES})

include_directories( ${CMAKE_CURRENT_BINARY_DIR} )

add_executable( ${PROJECT_NAME} ${${PROJECT_NAME}_SOURCE_LIST} ${${PROJECT_NAME}_HEADERS_MOC} ${${PROJECT_NAME}_FORMS_HEADERS} ${${PROJECT_NAME}_RESOURCES_RCC} )
target_link_libraries( ${PROJECT_NAME} ${QT_LIBRARIES} )


------------------------------------------------------------------------------

Время идёт, и вот натолкнулся я на необходимость написать своё gui приложение.
Прошлый опыт подсказал, что использовать буду qt.
Потому, что кросс-платформенный, open source, есть опыт использования.
Попытался взять установленную версию, но как то отсутствие namespace по умолчанию меня напугало.
Поэтому решился компилировать вручную.
В общем-то компилировать исходники из версии, которая была установлена нет возможности.
Сразу надо качать исходники и подбирать свои параметры сборки.
Прошу прощения за win32-msvc2005 но таковы условия на данный момент.
Для меня параметрами сборки стали:
configure -platform win32-msvc2005 -debug-and-release -opensource 
    -stl -rtti -qtnamespace gui <y
Я пытался собрать -static но из этого ничего не вышло (sqlite драйвер не захотел компилироваться).
В общем то ничего сложного, осталось подключить Qt и подсунуть всё это в CMake.
Для этого необходимо добавить в PATH путь к исполняемому файлу qmake, например у меня это в скрипте "_msvc_gen_2005.bat":
set QT_ROOT=D:\usr\qt-everywhere-opensource-src-4.7.4
set PATH=%PATH%;%QT_ROOT%\bin
Ну и соответственно добавить для поиска и компиляции:

1) Поиск и добавления путей и дополнительных CMake утилит в вашу систему сборки:
 find_package(Qt4 ${SEARCH_PARAMETERS} COMPONENTS QtCore QtGui QtMain)
    include( ${QT_USE_FILE} )
    add_definitions(${QT_DEFINITIONS})
2) Поиск и подключение необходимого namespace для компиляции:
    add_definitions( -DQT_NAMESPACE=gui )
3) Поиск всех необходимых файлов:
    file(GLOB ${PROJECT_NAME}_SOURCES *.cpp)
    file(GLOB ${PROJECT_NAME}_HEADERS *.h)
    file(GLOB ${PROJECT_NAME}_FORMS *.ui)
    file(GLOB ${PROJECT_NAME}_RESOURCES *.qrc)
    file(GLOB ${PROJECT_NAME}_SOURCE_LIST ${${PROJECT_NAME}_SOURCES} ${${PROJECT_NAME}_HEADERS} ${${PROJECT_NAME}_FORMS} ${${PROJECT_NAME}_RESOURCES} )
4) Запуск moc и обработчика ресурсов:
    QT4_WRAP_CPP(${PROJECT_NAME}_HEADERS_MOC ${${PROJECT_NAME}_HEADERS} )
    QT4_WRAP_UI(${PROJECT_NAME}_FORMS_HEADERS ${${PROJECT_NAME}_FORMS})
    QT4_ADD_RESOURCES(${PROJECT_NAME}_RESOURCES_RCC ${${PROJECT_NAME}_RESOURCES})
5) Подключение сгенерированных заголовков:
    include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
6) адекватная линковка:
    add_executable( ${PROJECT_NAME} ${${PROJECT_NAME}_SOURCE_LIST} ${${PROJECT_NAME}_HEADERS_MOC} ${${PROJECT_NAME}_FORMS_HEADERS} ${${PROJECT_NAME}_RESOURCES_RCC} )
    target_link_libraries( ${PROJECT_NAME} ${QT_LIBRARIES} )

В сумме не так и много:
find_package(Qt4 ${SEARCH_PARAMETERS} COMPONENTS QtCore QtGui QtMain)
include( ${QT_USE_FILE} )
add_definitions(${QT_DEFINITIONS})
add_definitions( -DQT_NAMESPACE=gui )

file(GLOB ${PROJECT_NAME}_SOURCES *.cpp)
file(GLOB ${PROJECT_NAME}_HEADERS *.h)
file(GLOB ${PROJECT_NAME}_FORMS *.ui)
file(GLOB ${PROJECT_NAME}_RESOURCES *.qrc)
file(GLOB ${PROJECT_NAME}_SOURCE_LIST ${${PROJECT_NAME}_SOURCES} ${${PROJECT_NAME}_HEADERS} ${${PROJECT_NAME}_FORMS} ${${PROJECT_NAME}_RESOURCES} )

QT4_WRAP_CPP(${PROJECT_NAME}_HEADERS_MOC ${${PROJECT_NAME}_HEADERS} )
QT4_WRAP_UI(${PROJECT_NAME}_FORMS_HEADERS ${${PROJECT_NAME}_FORMS})
QT4_ADD_RESOURCES(${PROJECT_NAME}_RESOURCES_RCC ${${PROJECT_NAME}_RESOURCES})

include_directories( ${CMAKE_CURRENT_BINARY_DIR} )

add_executable( ${PROJECT_NAME} ${${PROJECT_NAME}_SOURCE_LIST} ${${PROJECT_NAME}_HEADERS_MOC} ${${PROJECT_NAME}_FORMS_HEADERS} ${${PROJECT_NAME}_RESOURCES_RCC} )
target_link_libraries( ${PROJECT_NAME} ${QT_LIBRARIES} )