Дано
struct A {
int foo(double a, std::string& b) const;
};
Я могу создать указатель на функцию-член следующим образом:
typedef int (A::*PFN_FOO)(double, std::string&) const;
Достаточно просто, кроме того PFN_FOO
необходимо обновить, если A::foo
подпись меняется. Поскольку C ++ 11 вводит decltype
Может ли он быть использован для автоматического вывода подписи и создания typedef?
Да, конечно:
typedef decltype(&A::foo) PFN_FOO;
Вы также можете определить псевдоним типа через using
Ключевое слово (спасибо Мэтью М.):
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, чтобы получать более качественные сообщения.