Ответ 1
Да, конечно:
typedef decltype(&A::foo) PFN_FOO;
Вы также можете определить псевдоним типа с помощью using
ключевого слова (спасибо Matthieu M.):
using PFN_FOO = decltype(&A::foo);
Учитывая
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?
Да, конечно:
typedef decltype(&A::foo) PFN_FOO;
Вы также можете определить псевдоним типа с помощью using
ключевого слова (спасибо Matthieu M.):
using PFN_FOO = decltype(&A::foo);
Одна проблема: вы можете вывести только тип переменной, если эта переменная недвусмысленна.
Основная проблема с функциями заключается в том, что перегрузки означают, что их имен недостаточно для их идентификации. Поэтому использование 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 для получения более качественных сообщений.