Страницы

Поиск по вопросам

понедельник, 8 апреля 2019 г.

Упростить написание кода макросом

Имеется множество примерно таких методов:
void libvlc::Interop::LibVLCHelper::libvlc_media_player_set_media(libvlc_media_player_t * p_mp, libvlc_media_t * p_md) { if (!m_vlc_media_player_set_media) { m_vlc_media_player_set_media = m_libvlc_->Resolve(__func__); } (*m_vlc_media_player_set_media)(p_mp, p_md); }
Хочу сделать примерно такой макрос:
#define MF(t, x, name) if (!(x)) { (x) = m_libvlc_->Resolve(name); }
И определение на валидность упрощается соответственно до такого вида:
libvlc_media_player_t * libvlc::Interop::LibVLCHelper::libvlc_media_player_new(libvlc_instance_t * p_instance) { MF(vlc_media_player_new, m_vlc_media_player_new, __func__); return (*m_vlc_media_player_new)(p_instance); }
Да, он работает, но можно ли улучшить макрос до примерно такого вызова?
libvlc_media_player_t * libvlc::Interop::LibVLCHelper::libvlc_media_player_new(libvlc_instance_t * p_instance) { MF(vlc_media_player_new, __func__); return (*m_vlc_media_player_new)(p_instance); }
Для понятия: Макрос принимает тип, 1м параметром, подставляет m_(тут тип), и вид примерно такой:
#define MF(t, name) if (!(m_#t)) { (m_#t) = m_libvlc_->Resolve(name); }
Не очень хорошо дружу с макросами, и не могу понять как такое реализовать. Примечание: Имя поля всегда отличается от типа только добавочным m_


Ответ

Ваш код
#define MF(t, name) if (!(m_#t)) { (m_#t) = m_libvlc_->Resolve(name); }
почти правильный. Для token pasting («склеивания» токенов) нужно использовать удвоенный символ диеза.
#define MF(t, name) if (!(m_##t)) { (m_##t) = m_libvlc_->Resolve(name); }
(Практически одновременно тот же совет в комментарии дал @VTT.)

Комментариев нет:

Отправить комментарий