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

StackOverflow https://stackoverflow.com/questions/1572909

Вопрос

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

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

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

Я обычно нахожу, что когда вопрос о форме "хорошей идеей _______?" Ответ почти неизменно "нет!"

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top