Как можно получить указатель на функцию Eigen оператор () - PullRequest
2 голосов
/ 09 февраля 2012

Я хотел бы иметь указатель на функцию оператора собственной матрицы (). В частности, оператор () класса матрицы Eigen VectorXi, который принимает один индекс. То есть оператор, которым я пользуюсь при звонке:

VectorXi V(1);
...
VectorXi::Index i = 0;
VectorXi::Scalar& vi = V(i); // <-- this one

Что я пробовал:

VectorXi::Scalar& (*value_at_i)(VectorXi::Index i ) = &VectorXi::operator();

Но это дает мне очень длинную ошибку:

...: error: no matches converting function ‘operator()’ to type ‘int& (*)(Eigen::DenseIndex)’
/usr/local/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:124: error: candidates are: typename Eigen::internal::conditional<(bool)((Eigen::internal::traits<T>::Flags & Eigen::LvalueBit)), const typename Eigen::internal::traits<T>::Scalar&, typename Eigen::internal::conditional<Eigen::internal::is_arithmetic<typename Eigen::internal::traits<T>::Scalar>::value, typename Eigen::internal::traits<T>::Scalar, const typename Eigen::internal::traits<T>::Scalar>::type>::type Eigen::DenseCoeffsBase<Derived, 0>::operator()(typename Eigen::internal::traits<T>::Index, typename Eigen::internal::traits<T>::Index) const [with Derived = Eigen::Matrix<int, -0x00000000000000001, 1, 0, -0x00000000000000001, 1>]
/usr/local/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:184: error:                 typename Eigen::internal::conditional<(bool)((Eigen::internal::traits<T>::Flags & Eigen::LvalueBit)), const typename Eigen::internal::traits<T>::Scalar&, typename Eigen::internal::conditional<Eigen::internal::is_arithmetic<typename Eigen::internal::traits<T>::Scalar>::value, typename Eigen::internal::traits<T>::Scalar, const typename Eigen::internal::traits<T>::Scalar>::type>::type Eigen::DenseCoeffsBase<Derived, 0>::operator()(typename Eigen::internal::traits<T>::Index) const [with Derived = Eigen::Matrix<int, -0x00000000000000001, 1, 0, -0x00000000000000001, 1>]
/usr/local/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:405: error:                 typename Eigen::internal::traits<T>::Scalar& Eigen::DenseCoeffsBase<Derived, 1>::operator()(typename Eigen::internal::traits<T>::Index) [with Derived = Eigen::Matrix<int, -0x00000000000000001, 1, 0, -0x00000000000000001, 1>]
/usr/local/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:347: error:                 typename Eigen::internal::traits<T>::Scalar& Eigen::DenseCoeffsBase<Derived, 1>::operator()(typename Eigen::internal::traits<T>::Index, typename Eigen::internal::traits<T>::Index) [with Derived = Eigen::Matrix<int, -0x00000000000000001, 1, 0, -0x00000000000000001, 1>]

Как правильно получить указатель на функцию для этого оператора?

Ответы [ 3 ]

2 голосов
/ 09 февраля 2012

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

РЕДАКТИРОВАТЬ: Ниже приведен пример указателя на функции-члены в C ++ на оператор () класса T.

void (T::*op)(int) = &T::operator();
T t;
(t.*op)(5);
1 голос
/ 10 февраля 2012

Просто, чтобы сделать это немного более явным, и потому что мне было любопытно ... после ответа rasmus я попробовал следующий код, и он компилирует и выполняет то, что вы, похоже, хотите.

VectorXi T(5); T << 2,1,0,2,1; 
VectorXi IM(4); IM << 10,20,30,40; 
// IM maps 0 to 10, 1 to 20, 2 to 30 and 3 to 40

VectorXi::Scalar& (VectorXi::*get_value)(VectorXi::Index) = &VectorXi::operator();
VectorXi res = T.unaryExpr(bind1st(mem_fun(get_value), &IM));
// res is now 30, 20, 10, 30, 20
0 голосов
/ 09 февраля 2012

Решение - указать правильную перегрузку. То, что вы видите, это сбой разрешения перегрузки. Есть 4 кандидата, и ни один не соответствует подписи value_at_i.

Вы, конечно, хотите Eigen::internal::traits<T>::Scalar& Eigen::DenseCoeffsBase<Derived, 1>::operator()(typename Eigen::internal::traits<T>::Index) [with Derived = Eigen::Matrix<int, -0x00000000000000001, 1, 0, -0x00000000000000001, 1>].

Это противная подпись. Тем не менее, обратите внимание, что есть три важные части:

  • Тип возврата Eigen::internal::traits<T>::Scalar&
  • Тип класса Eigen::DenseCoeffsBase<Derived, 1>
  • Тип аргумента Eigen::internal::traits<T>::Index

Соответствующее правило для выбора перегрузки в этом случае весьма специфично: «Выбранная функция - это та, тип которой идентичен типу функции целевого типа, необходимого в контексте». Там нет регулировки, и есть даже примечание (13.4 / 7), показывающее это.

Поэтому мое текущее предположение состоит в том, что проблема заключается в типе класса Eigen::DenseCoeffsBase<Derived, 1>, который не VectorXi. Два других типа являются typedef, которые не вводят новые типы.

...