Skip to content

[3.4+current Bug] Eigen::internal::size(const T& x) function visible globally

Summary

During compilation the compiler will fail because of ambiguous overloads if

  1. The user includes Eigen/Dense
  2. Has a size(const T& x) function defined (even in another namespace)
  3. The user passes an expression to size()

This does not fail when (3) is excluded and everything compiles fine.

Environment

godbolt, tested with Eigen 3.3.9 (top executor), 3.4 (middle executor), and trunk (bottom executor).

https://godbolt.org/z/f9MboYja1

Minimal Example

(from godbolt)

#include <Eigen/Dense>

template <typename T>
inline constexpr auto size(const T& m) noexcept {
    return m.size();
}


int main() {
    Eigen::Matrix<double, -1, -1> A = Eigen::MatrixXd::Random(3, 3);
    // size(A); // is fine
    size(A.array() * A.array()); // compiler error
    return 0;
}

What is the current bug behavior?

Compilation fails

What is the expected correct behavior?

Compilation succeeds

Error Messages

Could not execute the program
Compiler returned: 1
Compiler stderr

<source>: In function 'int main()':
<source>:12:9: error: call of overloaded 'size(const Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<double, double>, const Eigen::ArrayWrapper<Eigen::Matrix<double, -1, -1> >, const Eigen::ArrayWrapper<Eigen::Matrix<double, -1, -1> > >)' is ambiguous
   12 |     size(A.array() * A.array()); // compiler error
      |     ~~~~^~~~~~~~~~~~~~~~~~~~~~~
<source>:4:23: note: candidate: 'constexpr auto size(const T&) [with T = Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<double, double>, const Eigen::ArrayWrapper<Eigen::Matrix<double, -1, -1> >, const Eigen::ArrayWrapper<Eigen::Matrix<double, -1, -1> > >]'
    4 | inline constexpr auto size(const T& m) noexcept {
      |                       ^~~~
In file included from /opt/compiler-explorer/libs/eigen/v3.4.0/Eigen/Core:162,
                 from /opt/compiler-explorer/libs/eigen/v3.4.0/Eigen/Dense:1,
                 from <source>:1:
/opt/compiler-explorer/libs/eigen/v3.4.0/Eigen/src/Core/util/Meta.h:479:23: note: candidate: 'constexpr Eigen::Index Eigen::internal::size(const T&) [with T = Eigen::CwiseBinaryOp<Eigen::internal::scalar_product_op<double, double>, const Eigen::ArrayWrapper<Eigen::Matrix<double, -1, -1> >, const Eigen::ArrayWrapper<Eigen::Matrix<double, -1, -1> > >; Eigen::Index = long int]'
  479 | EIGEN_CONSTEXPR Index size(const T& x) { return x.size(); }

Anything else that might help

I tried looking over Meta.h and am having a hard time parsing where / why this is happening. I even started to delete ifdefs to seeif something is going on there but was still getting the same error

  • Have a plan to fix this issue.