Re: [eigen] Compile error with nested arrays in Eigen 3.3

[ Thread Index | Date Index | More Archives ]


sorry for extremely late reply. I guess you managed to workaround this issue on your side, but we still need to figure-out something on Eigen's side.

What happens is that this operation is ambiguous because it can be interpreted in three different ways:

(1)  The one you probably expect: Array<Array3> + Array<Array3>  -> Array<Array3>

(2)  a + b is interpreted as the addition of b to each "scalar" of a, thus leading to a result of type Array< Array<Array3> >. This is the same operator instantiated for something like ArrayXf + float

(3) same as (2) but inverting the role of a and b.

Actually, the 2 and 3 options might be valid interpretations because it is perfectly fine to do:  Array<Array3> + Array3 but in theory our type promotion rules should not allow that. What deeply happens is that, because the implicit ctor:

  template<typename OtherDerived> Array(const EigenBase<OtherDerived> &other);

Array<Array3> and Array3 are seen as if they are convertible to each other wrt std::is_convertible. Of course, any attempt to actually convert a Array<Array3> to a Array3 will fail, and and an Array3f is not implicitly convertible to a Array<Array3>. So the remedy would to to disable this ctor when the underlying scalar types of this and OtherDerived are not compatible. Unfortunately, for ctor there is no other way than adding an ugly enable_if as a last parameter:

template<typename OtherDerived>
Array(const EigenBase<OtherDerived> &other,
          typename internal::enable_if<internal::is_convertible<typename OtherDerived::Scalar,Scalar>::value,UGLYTYPE>::type = UGLYTYPE())

I cannot think about a better solution to really solve this issue. I introduced a UGLYTYPE (instead of using a classic void* to prevent unexpected calls to this ctor.


On Tue, Mar 14, 2017 at 10:45 PM, Kevin Wampler <kwampler@xxxxxxxxx> wrote:

I’ve encountered some cases involving some nested arrays where code that used to compile in Eigen 3.2 no longer compiles in 3.3, and I’m wondering if there’s something I’m doing wrong or if support for this was intentionally removed.  Here’s an example:


    Eigen::Array<Eigen::Array3d,Eigen::Dynamic,1> a(7), b(7), c;

    for(int i = 0; i < 7; ++i) {

        a[i] = Eigen::Array3d::Random();

        b[i] = Eigen::Array3d::Random();


    c = a + b; // this line no longer compiles in 3.3


The marked line causes a compiler error complaining that the + operator cannot be unambiguously resolved.  It looks like there is a NumTraits specialization for Eigen::Array, so it *seems* like this sort of operation is supposed work, but it’s admittedly a bit non-standard so perhaps there’s something I’m missing.


Obviously I could rewrite the above code to avoid nested arrays, but it would be convenient for me is there was a way to keep the nested arrays but fix the compiler error.  Any suggestions? 


Mail converted by MHonArc 2.6.19+