Является ли реинтерпретация указателя на функцию-член "хорошей идеей"?
У меня есть рабочий поток, который содержит список "Действия потока" и работает через них как когда.
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)
)
);
Кажется, что это работает нормально, но я не уверен, что переосмысление указателя функции, как это "определенное" поведение, может кто-нибудь посоветовать?
4 ответа
Это определенно не поддерживается поведение и может привести к сбою вашей программы.
По сути, вам нужно сделать обертку для 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;
};
Это приложение возврата недействительным.
Я обычно нахожу это, когда вопрос имеет форму "Является ли _______ хорошей идеей?" ответ почти всегда "НЕТ!"
Это, вероятно, верно без контекста.