Я хотел бы объявить указатель функции членства в C++, который возвращает тот же тип указателя функции членства
Это не работает:
class MyClass {
public:
typedef FunctionPtr (MyClass::*FunctionPtr)();
}
Кто-то знает решение?
AndreyT ссылается на лучший ответ на GotW # 57 , так что я мог бы скопировать его здесь:
class MyClass {
public:
struct FunctionPtrProxy;
typedef FunctionPtrProxy (MyClass::*FunctionPtr)();
struct FunctionPtrProxy
{
FunctionPtrProxy(FunctionPtr pp ) : p( pp ) { }
operator FunctionPtr() { return p; }
FunctionPtr p;
}
}
То, что вы пытаетесь сделать, невозможно - тип возвращаемого значения функции - это тип самой функции, который еще не известен, поэтому это приводит к бесконечному циклу.
Нет никакого способа чтобы добиться именно этого. Фактически, функции-члены здесь не имеют значения: нет способа объявить обычную функцию, которая возвращает указатель на свой собственный тип функции. Объявление будет бесконечно рекурсивным.
В случае обычной функции вы можете использовать тип void (*) ()
как «универсальный» тип указателя на функцию (точно так же, как void *
часто используется для данных типы). Для указателей функций-членов это будет тип void (A :: *) ()
. Однако для этой цели вам придется использовать reinterpret_cast
. Однако это использование (двустороннее преобразование) происходит тогда, когда определено поведение reinterpret_cast
.
Конечно, вам придется использовать приведение типов для преобразования указателя в этот тип и обратно.AFAIK, есть элегантные решения на основе шаблонов с промежуточным временным объектом шаблона, который выполняет преобразование.
Вы также можете взглянуть на эту запись GotW .
P.S. Обратите внимание, что использование типа void *
в качестве промежуточного типа для указателей функций запрещено языком. Хотя такое незаконное использование может показаться «работающим» с указателями обычных функций, у него нет абсолютно никаких шансов работать с указателями функций-членов. Указатели на функции-члены обычно представляют собой нетривиальные объекты, размер которых превышает размер указателя void *
.