Можно ли использовать C ++ 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подпись меняется. Поскольку C ++ 11 вводит decltypeМожет ли он быть использован для автоматического вывода подписи и создания typedef?

30

Решение

Да, конечно:

typedef decltype(&A::foo) PFN_FOO;

Вы также можете определить псевдоним типа через using Ключевое слово (спасибо Мэтью М.):

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

43

Другие решения

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

Основная проблема с функциями заключается в том, что перегрузки означает, что одних их имен недостаточно для их идентификации. Поэтому с помощью 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, чтобы получать более качественные сообщения.

19

По вопросам рекламы [email protected]