Является ли реинтерпретация указателя на функцию-член "хорошей идеей"?

У меня есть рабочий поток, который содержит список "Действия потока" и работает через них как когда.

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;
};

Это приложение возврата недействительным.

Я обычно нахожу это, когда вопрос имеет форму "Является ли _______ хорошей идеей?" ответ почти всегда "НЕТ!"

Это, вероятно, верно без контекста.

Другие вопросы по тегам