2016-10-19 7 views
2

Я объявляю конкретную функцию клавиатуры обратного вызова, так как это в моем коде:Что означает T :: * в объявлении списка параметров функции?

void keyboardEventCallback(const pcl::visualization::KeyboardEvent &event, void* viewer_void, void* widget_void); 

Событие клавиатуры реальное событие передается функции обратного вызова viewer_void параметр является указателем на класс PCLVisualizer, который создает окно рендеринг и widget_void - это указатель на виджет, который взаимодействует с Qt.

В документации к ПКЛ, функция регистрации передает аргументы для регистрации функции клавиатуры, как

boost::signals2::connection registerKeyboardCallback(void(T::*callback)(const pcl::visualization::KeyboardEvent&, void*), T& instance, void* cookie=nullptr) 

Так что мой вопрос, , что есть смысл T::* внутри функции регистрации декларации и почему я не позволил передать это:

m_vis->registerKeyboardCallback(keyboardEventCallback, (void*)&m_vis, (void*)this); 

где m_vis является визуализатор, keyboardcallback - это обратный вызов, и это виджет.

Почему я не могу зарегистрироваться так. Это для библиотеки облаков точек.

ответ

1

Это синтаксис для функций-членов.

Пример:

class A{ 
    int giveMe5(); 
}; 

&A::giveMe5; // will be of type int(A::*)() 

Почему типа отличаются от свободных функций и статических функций-членов? Поскольку функции-члены имеют неявный параметр, который указывает на объект, на который вызывается функция.

Посмотрите: https://isocpp.org/wiki/faq/pointers-to-members#fnptr-vs-memfnptr-types

3

каково значение T :: * внутри функции регистрации декларации

Это синтаксис указателя на член. Давайте посмотрим на весь тип и имя параметра:

void(T::*callback)(const pcl::visualization::KeyboardEvent&, void*) 

Это объявление переменной с именем callback. Это указатель для функции-члена. Точнее, это указатель на функцию-член класса T.

Если мы возьмем имя из типа, мы видим вещи более ясно:

// class name ---v  v------- parameters 
      void(T::*)(const pcl::visualization::KeyboardEvent&, void*) 
//   ^---- return type 

Это на самом деле, указатель на функцию член класса T, что возвращение void. Это функция, которая принимает строго два параметра: a const pcl::visualization::KeyboardEvent& и void*.

почему я не позволил пройти этот

Это просто.Посмотрите на тип вашей функции:

using func_type = decltype(keyboardEventCallback); 
// hint: the type is: void(*)(const pcl::visualization::KeyboardEvent&, void*, void*) 

Давайте сравним сторону два типа бок:

void(*)(const pcl::visualization::KeyboardEvent&, void*, void*) 
void(T::*)(const pcl::visualization::KeyboardEvent&, void*) 

Во-первых, ваша функция не является функцией-членом, это простой указатель на функцию. Это не тот же тип. Затем у вас есть три аргумента, так как тип параметра запрашивает только два. Это другое.


Теперь, как вы можете это исправить?

Вы можете использовать лямбда:

auto myCallback = [](const pcl::visualization::KeyboardEvent& e, void* c) { /* ... */ } 

using lambdaType = decltype(myCallback); 

// Be careful here, we don't want our lambda to go out of scope when it is called. 
m_vis->registerKeyboardCallback(&lambdaType::operator(), myCallback, this); 

Или еще проще: просто определить keyboardEventCallback внутри своего класса, и отправить его:

// don't forget: keyboardEventCallback must receive the same parameter as asked. 
m_vis->registerKeyboardCallback(&MyClass::keyboardEventCallback, *this, this);