This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen

Bug 969

Summary: Ambiguous calls to Eigen::Ref
Product: Eigen Reporter: Pierre G. <pierre.gergondet>
Component: Core - generalAssignee: Nobody <eigen.nobody>
Status: RESOLVED FIXED    
Severity: Compilation Problem CC: christoph.roesmann, chtz, gael.guennebaud, jacob.benoit.1, pierre.gergondet, trebor.fireclaws
Priority: Normal    
Version: 3.2   
Hardware: All   
OS: Linux   
Whiteboard:
Bug Depends on:    
Bug Blocks: 558    

Description Pierre G. 2015-02-23 14:20:32 UTC
Hello,

The following code will produce an ambiguous call at compilation with Eigen >= 3.2.3 and the current dev version (on g++ 4.8.2 and clang 3.4.2): 

#include <Eigen/Core>

typedef Eigen::Ref<Eigen::MatrixXd> RefMat;
typedef Eigen::Ref<Eigen::VectorXi> RefVecInt;

void fun(RefMat Q) {}

void fun(RefVecInt kx) {}

int main(int, char**)
{
  Eigen::MatrixXd M;
  fun(M);
  return 0;
}

The issue was introduced by commit 06d4fff (https://bitbucket.org/eigen/eigen/commits/06d4fff20a93/) the culprit being the removal of the enable_if from the template parameters.

Best regards,
Comment 1 Christoph Hertzberg 2015-02-24 20:48:51 UTC
When submitting Bug 903, I admittedly forgot that enable_if also helps resolving which function to call.
Unless someone knows a better alternative, I'm ok with reverting the change except for the ThisConstantIsPrivateInPlainObjectBase hack (this could actually also be included into the enable_if).
Comment 2 Gael Guennebaud 2015-03-02 08:09:27 UTC
I also do not see any other solution but enable_if. Perhaps it would be possible to defer to enable_if to RefBase's ctor so that Ref's ctor remains clean. Though, I don't know whether SFINAE will still apply.
Comment 3 Gael Guennebaud 2015-03-06 17:53:45 UTC
Fixed using enable_if: https://bitbucket.org/eigen/eigen/commits/32809fa3264a/
Comment 4 Roberto Cavicchioli 2015-06-22 16:25:43 UTC
Sorry to bother, but with last update (3.2.5) this code gives me ambiguity in compilation (Windows with MSVC 2013)

static void classicalCapacitanceComponents(Ref<ArrayXd> Cs, Ref<ArrayXd> Cs_el, Ref<ArrayXd> Cs_hol, const double& phif, const Ref<const ArrayXd>& Cs_class, const Ref<const ArrayXd>& Cmaj_class)
{
	if (phif > 0.0)
	{
		Cs_hol = Cmaj_class;
		Cs = Cs_class;
		Cs_el = Cs - Cs_hol;
	}
	else
	{
		Cs_el = Cmaj_class;
		Cs = Cs_class;
		Cs_hol = Cs - Cs_el;
	}
}

Compilation says that operator = have 3 overloads: DenseBase, ArrayBase and MapBase.

As a workaround I've modified as:

static void classicalCapacitanceComponents(Ref<ArrayXd> Cs, Ref<ArrayXd> Cs_el, Ref<ArrayXd> Cs_hol, const double& phif, const Ref<const ArrayXd>& Cs_class, const Ref<const ArrayXd>& Cmaj_class)
{
	if (phif > 0.0)
	{
		Cs_hol.array() = Cmaj_class;
		Cs.array() = Cs_class;
		Cs_el.array() = Cs - Cs_hol;
	}
	else
	{
		Cs_el.array() = Cmaj_class;
		Cs.array() = Cs_class;
		Cs_hol.array() = Cs - Cs_el;
	}
}

adding .array() to all output variables, but I think there is a better way to do it..

Regards
Comment 5 Gael Guennebaud 2015-06-22 20:55:14 UTC
I cannot reproduce here. The only change that could explain this behavior is in src/Core/util/Macros.h. In this file, line 317, could you try to change 1800 to 1900, such that line 317 reads:

#if defined(_MSC_VER) && (_MSC_VER < 1900) && (!defined(__INTEL_COMPILER))

See bug 1000.
Comment 6 Roberto Cavicchioli 2015-06-22 21:14:00 UTC
Thanks Gael, 
this seems to work.
I forgot to include also the fact that I was calling the function from a Map<ArrayXd> as the Ref<ArrayXd> parameter.

Thanks again,

Regards,

Roberto
Comment 7 Gael Guennebaud 2015-06-22 21:21:04 UTC
so I guess you are using MSVC 2013. The problem now is that reverting to _MSC_VER < 1900 will restore the compilation issue of bug 1000...
Comment 8 Gael Guennebaud 2015-06-23 14:24:51 UTC
Ok, since this issue does not occur in the devel branch, the following changeset should fix the issue in the 3.2 branch without having to change the previous line in Macros.h:

https://bitbucket.org/eigen/eigen/commits/dd05500d17e3/

Roberto: please let us know whether this is working for you, in which case I'll make a 3.2.6.
Comment 9 Roberto Cavicchioli 2015-06-23 14:41:46 UTC
Sorry Gael, but this doesn't solve my issues.
MSVC keeps complaining about the multiple overload conversions.

Hoping it helps, I attach the following output:

d:\shared_internal\mdlab_trunk\c_conversion\substrate potential\src\substratePotentialFunctions.h(126) : error C2666:
'Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>::operator =' : 3 overloads have similar conversions
        d:\shared_internal\mdlab_trunk\c_conversion\eigen_lib\eigen\eigen\src/Core/Ref.h(224): could be 'Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>
        &Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>::operator =(const Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>> &)'
        d:\shared_internal\mdlab_trunk\c_conversion\eigen_lib\eigen\eigen\src/Core/DenseBase.h(255): or       'Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>
        &Eigen::DenseBase<Derived>::operator =(const Eigen::DenseBase<Derived> &)'
        with
        [
            Derived=Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>
        ]
        d:\shared_internal\mdlab_trunk\c_conversion\eigen_lib\eigen\eigen\src/Core/ArrayBase.h(121): or       'Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>
        &Eigen::ArrayBase<Derived>::operator =(const Eigen::ArrayBase<Derived> &)'
        with
        [
            Derived=Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>
        ]
        d:\shared_internal\mdlab_trunk\c_conversion\eigen_lib\eigen\eigen\src/Core/MapBase.h(232): or       'Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>
        &Eigen::MapBase<Derived,1>::operator =(const Eigen::MapBase<Derived,1> &)'
        with
        [
            Derived=Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>
        ]
        d:\shared_internal\mdlab_trunk\c_conversion\eigen_lib\eigen\eigen\src/Core/Ref.h(155): or
        'Eigen::RefBase<Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>> &Eigen::RefBase<Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>>::operator =(const
        Eigen::RefBase<Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>> &)'
        d:\shared_internal\mdlab_trunk\c_conversion\eigen_lib\eigen\eigen\src/Core/EigenBase.h(107): or       'Derived &Eigen::DenseBase<Derived>::operator
        =<Eigen::Ref<const Eigen::ArrayXd,0,Eigen::InnerStride<1>>>(const Eigen::EigenBase<Eigen::Ref<const Eigen::ArrayXd,0,Eigen::InnerStride<1>>> &)'
        with
        [
            Derived=Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>
        ]
        d:\shared_internal\mdlab_trunk\c_conversion\eigen_lib\eigen\eigen\src/Core/Assign.h(550): or       'Derived &Eigen::DenseBase<Derived>::operator
        =<Eigen::Ref<const Eigen::ArrayXd,0,Eigen::InnerStride<1>>>(const Eigen::DenseBase<Eigen::Ref<const Eigen::ArrayXd,0,Eigen::InnerStride<1>>> &)'
        with
        [
            Derived=Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>
        ]
        while trying to match the argument list '(Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>, const Eigen::Ref<const
        Eigen::ArrayXd,0,Eigen::InnerStride<1>>)'
Comment 10 Christoph Rösmann 2015-06-26 12:00:46 UTC
Hello,

I also having problems with Ref and VS2013 since Eigen 3.2.5 and I think it is related to this discussion.

The following code compiles well under VS2013 (Win7) and Eigen 3.2.4.
It does not compile since Eigen 3.2.5:

#include <Eigen/Core>

void foo(Eigen::Ref<Eigen::Vector3d> vec_in)
{
	Eigen::Vector3d vec2;
	vec_in = vec2; // without this assignment everything compiles fine.
}

int main()
{

	Eigen::Vector3d vec;
	foo(vec);
	return 0;
}

The error log is similar to the one from Roberto.
The main error message is:
error C2666: 'Eigen::Ref<Eigen::ArrayXd,0,Eigen::InnerStride<1>>::operator =' : 3 overloads have similar conversions

The suggested patch https://bitbucket.org/eigen/eigen/commits/dd05500d17e3/
does not seems to work for me.
Changing Macros.h did the trick, but your are right, it does not fix this issue at all.
Comment 11 Gael Guennebaud 2015-06-26 12:10:46 UTC
I've pushed the Macros.h change. Bug 1000 was not about vc2013 but a very preliminary  version of what will soon be vc2015 (1900).
Comment 12 Nobody 2019-12-04 14:18:33 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/969.