Указатель на функцию-член, который возвращает тот же тип указателя на функцию-член

Я хотел бы объявить указатель на функцию-член в 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;
        }

} 

То, что вы пытаетесь сделать, невозможно - тип возвращаемой функции - это тип самой функции, который еще не известен, поэтому он ведет к бесконечному циклу.

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