Является ли переосмысление указателя функции-члена «хорошей идеей»?
-
21-09-2019 - |
Вопрос
У меня есть рабочий поток, который содержит список «Действий потока» и работает через них как «когда».
template <class T> class ThreadAction
{
public:
typedef void (T::*action)();
ThreadAction(T* t, action f) :
func(f),obj(t) {}
void operator()() { (obj->*func)(); }
void (T::*func)();
T* obj;
};
Обычно это называется так
myActionThread->addAction(
new ThreadAction<TheirClass>(this, &TheirClass::enable)
);
Что работало нормально, пока
void TheirClass::enable()
был изменен на
bool TheirClass::enable()
К сожалению, мы не можем изменить его обратно, потому что другим вещам нужен новый формат (а перегрузки не могут различаться только по типу возвращаемого значения).
я попробовал
myActionThread->addAction(
new ThreadAction<TheirClass>(this,
reinterpret_cast<void(TheirClass::*)>(&TheirClass::enable)
)
);
Кажется, это работает нормально, но я не уверен, что такая переинтерпретация указателя функции является «определенным» поведением, может кто-нибудь посоветовать?
Решение
Это определенно нет поддерживаемое поведение и потенциально может привести к сбою вашей программы.
По сути, вам нужно сделать обертку для TheirClass::enable()
который будет иметь правильный тип возвращаемого значения.Простого однострочника будет достаточно:
public:
void enableWrapper() { enable(); };
Тогда позвоните:
myActionThread->addAction(
new ThreadAction<TheirClass>(this, &TheirClass::enableWrapper)
);
Если вы не можете изменить TheirClass
напрямую, а затем создайте простой подкласс или вспомогательный класс, реализующий оболочку.
Другие советы
Эээ, насколько я понял, вы выполняете кастинг из метода, который возвращает bool
к методу, который возвращает void
?
Это может быть опасно, в зависимости от используемого соглашения о вызове/возврате.Ты мощь забудьте извлечь возвращаемое значение или переопределить значение регистра возвращаемым значением.
Не хорошая идея.Рассмотрите возможность добавления дополнительного параметра шаблона для типа возвращаемого значения:
template <class T, typename RetType> class ThreadAction
{
public:
typedef RetType (T::*action)();
ThreadAction(T* t, action f) :
func(f),obj(t) {}
RetType operator()() { return (obj->*func)(); }
RetType (T::*func)();
T* obj;
};
Это приложение возврат недействительным.
Я обычно нахожу, что когда вопрос о форме "хорошей идеей _______?" Ответ почти неизменно "нет!"
Вероятно, это верно без контекста.