Prohibit macro expansion of min/max without losing Argument Dependent Lookup
Submitted by Alexander Werner
Assigned to Nobody
Link to original bugzilla bug (#701)
Version: 3.2
Description
Created attachment 389
Patch to resolve the problem
== Problem ==
When using Eigen::AutoDiffScalar<T> as a datatype in an
Eigen::Matrix<>, some algorithms like Eigen::SVD do not compile.
There are multiple problems - the most difficult one to solve are
the calls to min.
The situation is somewhat more complicated because Visual C++ defines
min as a macro. This enforces Eigen code to disable argument dependant
lookup on these calls "(min)(foo,bar)" - which is very ugly.
== Solution ==
The solution to just #undef min is not allowed because it may break user code.
Unfortunately Visual C++ (and now also g++) provide
#pragma push_macro to same contents of a macro.
So the first problem can be resolved by putting the following statement at
the top of all Eigen includes:
#pragma push_macro("min")
#undef min
And reverting this at the bottom of all includes:
#pragma pop_macro("min")
After this it is possible to enable argument dependant lookup on calls to
min(). But since Eigen code always does:
using std::min;
we import a template in the local namespace which then catches all occurences of
min(TYPE1,TYPE2); where TYPE1==TYPE2
So if TYPE1==AutoDiffScalar<T> this fails to compile because std::min cannot
handle AutoDiffScalar. Even if a specialized function
min(AutoDiffScalar<T>, AutoDiffScalar<T>) is provided this fails
because there is an ambiguity.
The solution provided here is to remove all occurences of
using std::min;
And provide
Eigen::min functions which are not templated. I do not like this solution,
but at least it does the job. Probably C++11 could do a better job
here but I gather this is not an option.
Patch 389, "Patch to resolve the problem":
eigen_min_max.patch