Указатель на функцию-член, который возвращает тот же тип указателя на функцию-член
Я хотел бы объявить указатель на функцию-член в C++, который возвращает тот же тип указателя на функцию-член
Это не работает:
class MyClass {
public:
typedef FunctionPtr (MyClass::*FunctionPtr)();
}
Кто-нибудь знает решение?
3 ответа
Нет способа достичь именно этого. Фактически, функции-члены здесь не имеют значения: нет способа объявить обычную функцию, которая возвращает указатель на свой собственный тип функции. Объявление будет бесконечно рекурсивным.
В случае обычной функции вы можете использовать void (*)()
тип как "универсальный" тип указателя функции (так же, как void *
часто используется для типов данных). Для указателей на функции-члены, которые будут void (A::*)()
тип. Вы должны использовать reinterpret_cast
для этой цели, хотя. Тем не менее, это использование (обратное преобразование) оказывается тем, когда поведение reinterpret_cast
определено.
Конечно, вы будете вынуждены использовать приведение для преобразования указателя в и из этого типа. AFAIK, существуют элегантные основанные на шаблонах решения с промежуточным временным объектом шаблона, который выполняет приведение.
Вы также можете взглянуть на эту запись GotW.
PS Обратите внимание, что используя void *
тип как промежуточный тип для указателей на функции запрещен языком. Хотя такое незаконное использование может показаться "работающим" с обычными указателями на функции, у него нет абсолютно никаких шансов работать с указателями на функции-члены. Указатели на функции-члены обычно являются нетривиальными объектами, размер которых превышает размер void *
указатель.
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;
}
}
То, что вы пытаетесь сделать, невозможно - тип возвращаемой функции - это тип самой функции, который еще не известен, поэтому он ведет к бесконечному циклу.