This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Ambiguous overloads with Eigen::Ref

Tags: None
(comma "," separated)
martin_
Registered Member
Posts
5
Karma
0

Ambiguous overloads with Eigen::Ref

Sun Aug 10, 2014 9:41 am
Hi,

I would like to create a class which takes fixed-size expressions as input to constructors. I tried using Eigen::Ref but the call is ambiguous. I am a bit confused: I thought each template instantiation introduces a new type.

Is there any other way to achieve this?

Here is some code that shows what I would like to do (Ideally without the commented-out constructors).

Code: Select all
#include <iostream>
#include <Eigen/Core>

class Foo
{
  public:

//    Foo (const Eigen::Array3f& array3f)
//    {
//      std::cout << "Constructor array3f" << std::endl;
//    }

//    Foo (const Eigen::Array4f& array4f)
//    {
//      std::cout << "Constructor array4f" << std::endl;
//    }

    Foo (const Eigen::Ref <const Eigen::Array3f>& array3f)
    {
      std::cout << "Constructor array3f ref" << std::endl;
    }

    Foo (const Eigen::Ref <const Eigen::Array4f>& array4f)
    {
      std::cout << "Constructor array4f ref" << std::endl;
    }
};

int main ()
{
  Eigen::Array3f array3f;
  Eigen::Array4f array4f;

  // Compiles
  {
    Foo f3 (Eigen::Ref <const Eigen::Array3f> (array3f.head <3> ()));
    Foo f4 (Eigen::Ref <const Eigen::Array4f> (array4f.head <4> ()));
  }

  // Compiles if I comment in the respective constructors.
  {
    Foo f3 (array3f);
    Foo f4 (array4f);
  }

  // Doesn't compile: 'call to constructor of 'Foo' is ambiguous'
  {
    Foo f3 (array3f.head <3> ());
    Foo f4 (array4f.head <4> ());
  }

  return (0);
}
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
You have to exploit SFINAE with the enable_if mechanism to disambiguate between the different constructors, e.g.:

Code: Select all
    template<typename Derived>
    Foo(const Eigen::ArrayBase<Derived>& a, typename Eigen::internal::enable_if<Derived::IsVectorAtCompileTime && Derived::SizeAtCompileTime==3, Derived*>::type = 0)
    {
      std::cout << "Constructor array3" << std::endl;
    }
   
    template<typename Derived>
    Foo(const Eigen::ArrayBase<Derived>& a, typename Eigen::internal::enable_if<Derived::IsVectorAtCompileTime && Derived::SizeAtCompileTime==4, Derived*>::type = 0)
    {
      std::cout << "Constructor array4" << std::endl;
    }


and of course feel free to use the more standard std::enable_if implementation if C++11 is ok for you, or also boost::enable_if if you already use boost.
martin_
Registered Member
Posts
5
Karma
0
Great. Thanks for the quick help.


Bookmarks



Who is online

Registered users: Bing [Bot], claydoh, Google [Bot], rblackwell, Yahoo [Bot]