Я смотрел на реализацию is_class
шаблон в Повышении, и столкнулся с некоторым синтаксисом, который я не могу легко дешифровать.
template <class U> static ::boost::type_traits::yes_type is_class_tester(void(U::*)(void));
template <class U> static ::boost::type_traits::no_type is_class_tester(...);
Как я интерпретирую void(U::*)(void)
выше? Я знаком с C, таким образом, это кажется несколько аналогичным void(*)(void)
, но я не понимаю как U::
изменяет указатель. Кто-либо может помочь?
Спасибо
*
указывает на указатель, потому что вы можете получить доступ к его содержимому, написав * p
. U :: *
указывает указатель на член класса U
. Вы можете получить доступ к его содержимому, написав u. * P
или pu -> * p
(где u
является экземпляром U
) .
Итак, в вашем примере void (U :: *) (void)
- это указатель на член U
, который является функцией без аргументов и не возвращает значения.
Пример:
class C { void foo() {} };
typedef void (C::*c_func_ptr)(void);
c_func_ptr myPointer = &C::foo;
Это указатель на функцию-член класса U. он очень похож на
void (*) (void)
, но указывает на функцию-член класса U.
Вы правы, это аналог указателя на функцию. Скорее, это указатель на функцию-член, где член принадлежит к классу U
.
Разница в типе необходима, потому что функции-члены имеют неявный указатель this
, так как они не могут быть вызваны без экземпляра. Избавление от шаблона может немного упростить задачу:
struct foo
{
void bar(void);
};
void (*) (void)
не подойдет, поскольку здесь нет способа передать экземпляр класса. Скорее, нам нужно:
void (foo::*)(void)
Это означает, что для этого указателя функции требуется экземпляр foo
.
Как бы то ни было, вы используете их так:
typedef void (foo::*func_ptr)(void);
foo f;
foo* fp = &f;
func_ptr func = &foo::bar;
(f.*func)();
(fp->*func)();
Начните с U, затем работайте наизнанку.
Объявленный тип - это указатель на функцию-член из класса U, принимающую пустые аргументы и возвращающую пустоту.