Method unaryExpr() does not support function pointers in Eigen 3.4rc1
Summary
MatrixBase's method unaryExpr() does not support function pointers in Eigen 3.4rc1, while this works well in Eigen 3.3.
The change of behavior was introduced in commit 11f55b29. As a consequence, unaryExpr() does not support function pointers in Eigen 3.4rc1, branch 3.4, and master. I am not sure if the support for function pointers was dropped for performance reasons. The quick reference guide states
It is also very simple to apply any user defined function foo using DenseBase::unaryExpr together with std::ptr_fun (c++03), std::ref (c++11), or lambdas (c++11):
mat1.unaryExpr(std::ptr_fun(foo)); mat1.unaryExpr(std::ref(foo)); mat1.unaryExpr([](double x) { return foo(x); });
All these three methods work well in all versions of Eigen I have tested, so these can be used as alternatives.
Nevertheless, I could not find any information on this in the release notes for Eigen 3.4.
Let me therefore propose to add support for function pointers again and add a regression test. If this is not intended we should add a note to section Changes that might impact existing code in the release notes.
Environment
- Operating System : Linux
- Architecture : x64
- Eigen Version : 3.4rc1
- Compiler Version : Gcc8.3
- Compile Flags : none
- Vector Extension : none
Minimal Example
#include <iostream>
#include <Eigen/Core>
double f(const double x) { return 2 * x; }
int main() {
Eigen::VectorXd v = Eigen::VectorXd::LinSpaced(10, 0, 9);
std::cout << v.transpose() << std::endl;
// works in Eigen 3.3, but not in 3.4 or master
std::cout << v.unaryExpr(&f).transpose() << std::endl;
// works well in all versions of Eigen (see quick reference guide)
std::cout << v.unaryExpr(std::ptr_fun(f)).transpose() << std::endl;
std::cout << v.unaryExpr(std::ref(f)).transpose() << std::endl;
std::cout << v.unaryExpr([](double x) { return f(x); }).transpose()
<< std::endl;
return EXIT_SUCCESS;
}
Steps to reproduce
- Save the above code snippet to file
test_unaryExpr.cpp
. - Try to compile it using
g++ -I ~/path/to/eigen/ -o test_unaryExpr test_unaryExpr.cpp
with different versions of Eigen.
What is the current bug behavior?
The code does not compile and the main error message is
Eigen/src/Core/CoreEvaluators.h:595:9: error: base type ‘double (*)(double)’ fails to be a struct or class type
class Data : private UnaryOp
^~~~
What is the expected correct behavior?
Code test_unaryExpr.cpp
successfully compiles without warnings and program test_unaryExpr
runs without errors.
Relevant logs
The expected output is
$ ./test_unaryExpr
0 1 2 3 4 5 6 7 8 9
0 2 4 6 8 10 12 14 16 18
0 2 4 6 8 10 12 14 16 18
0 2 4 6 8 10 12 14 16 18
0 2 4 6 8 10 12 14 16 18
$