Подтвердить что ты не робот

Может ли С++ 11 decltype использоваться для создания typedef для указателя функции из существующей функции?

Учитывая

struct A { 
    int foo(double a, std::string& b) const;
};

Я могу создать указатель функции-члена следующим образом:

typedef int (A::*PFN_FOO)(double, std::string&) const;

Достаточно легко, за исключением того, что PFN_FOO необходимо обновить, если изменяется подпись A::foo. Поскольку С++ 11 вводит decltype, может ли он использоваться для автоматического вывода подписи и создания typedef?

4b9b3361

Ответ 1

Да, конечно:

typedef decltype(&A::foo) PFN_FOO;

Доказательство здесь

Вы также можете определить псевдоним типа с помощью using ключевого слова (спасибо Matthieu M.):

using PFN_FOO = decltype(&A::foo);

Ответ 2

Одна проблема: вы можете вывести только тип переменной, если эта переменная недвусмысленна.

Основная проблема с функциями заключается в том, что перегрузки означают, что их имен недостаточно для их идентификации. Поэтому использование decltype не выполняется, если вы когда-либо вводите перегрузку foo в A.

struct A {
    void foo() const;
    void foo(int) const;
};

using PFN_FOO = decltype(A::foo);
source.cpp:6:36: error: decltype cannot resolve address of overloaded function

Не уверен, что вы будете так много зарабатывать...

С другой стороны, вы можете фактически использовать псевдоним и проверить, что псевдоним прав:

struct A {
    void foo() const;
    void foo(int) const;
};

using PFN_FOO = void (A::*)(int) const;

static_assert(std::is_same<PFN_FOO, decltype(static_cast<PFN_FOO>(&A::foo))>::value,
     "Ooops, need to update signature of PFN_FOO!");

Примечание: не уверен, что это лучший способ протестировать, в основном все, что вам нужно, это часть static_cast, я просто хотел спрятать сообщение об ошибке рядом. Возможно, вам понадобится что-то вроде SFINAE для получения более качественных сообщений.