Думаю, что старые читатели блога знают, что я большой поклонник программирования на бумаге. Этому здесь было посвящено несколько заметок, начиная с одной и самых старых. И я, по прежнему активно мараю бумагу перед тем, как сделать что-нибудь новое и/или важное.
Однако, если серьезно упороться C++ными шаблонами, то пользы от предварительного программирования на бумаге оказывается заметно меньше. Думаю, это потому, что C++ я знаю не очень хорошо, поэтому не могу на бумаге написать сложный код с шаблонами так, чтобы затем не пришлось его сильно переделывать из-за того, что компилятор на тему использования шаблонов думает совсем по-другому :( Из-за этого намного проще писать код прямо в Vim-е, пытаться его компилировать, сразу же исправлять те места, по которым у меня с компилятором (и со стандартном) обнаруживаются принципиальные расхождения. Затем все повторяется снова и снова, пока я не получаю то, что мне нужно, причем так, чтобы это компилировалось и VC++, и Gcc, и clang.
Однако, от того, что код начинает появляться прямо сидя за компьютером, зачастую я не знаю, как именно будет использовать какая-то новая сущность. Поэтому на начальном этапе настоящая беда и комментариями, и с самими наименованиями в программе. А для того, чтобы все это можно было со временем доработать напильником и довести до приличного состояния, код щедро размечается тегами FIXME. И выглядит это приблизительно вот так:
template< typename COLLECTING_MSG, typename TRAITS = runtime_size_traits_t, typename LOCK_TYPE = std::mutex > //FIXME: should it be final or not? class mbox_template_t final : public ::so_5::abstract_message_box_t , protected TRAITS::size_specific_base_type , protected ::so_5::details::lock_holder_detector< LOCK_TYPE >::type { using specific_base_type = typename TRAITS::size_specific_base_type; //FIXME: document this! using config_type = details::config_type< COLLECTING_MSG, TRAITS, LOCK_TYPE >; //FIXME: document this! using messages_collected_builder_t = typename details::collected_bunch_type_selector< config_type >::builder_type; public : //FIXME: document this! using messages_collected_t = typename details::collected_bunch_type_selector< config_type >::message_type; private : //FIXME: document this! using messages_collected_subscription_type = typename std::conditional< is_mutable_message< COLLECTING_MSG >::value, mutable_msg< messages_collected_t >, messages_collected_t > ::type; public : //FIXME: what about message tracing traits? template< typename... ARGS > mbox_template_t( mbox_id_t mbox_id, ARGS &&... args ) : specific_base_type( mbox_id, std::forward<ARGS>(args)... ) { details::check_mutability_validity_for_target_mbox<config_type>( this->m_target ); } |
PS. Ну и еще наброшу на тему C++ных шаблонов. Когда ими реально упарываешься, то начинаешь совсем по другому относиться к спорам на тему того, что вместо C++ можно использовать plain old C или Rust. Программирование на шаблонах C++ -- это, блин, совсем другой подход к программированию. Ни Rust, ни, тем более, C, тут и рядом не стояли. Т.е. сделать одно и тоже можно будет на разных языках, но это будут совершенно разные решения, абсолютно не похожие на друг друга.