Re: [eigen] std::swap doesn't work on Map

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


The problem with this is that in the case when typename A == typename
B, our overload is not guaranteed to get called, I guess the
first-defined swap() gets called, and in the example program below, at
least with GCC 4.4, it doesn't get called.

Benoit

#include<iostream>
#include<Eigen/Core>

using namespace Eigen;

namespace std {
  template<typename A,typename B> void swap(A& a, B& b)
  {
    std::cout << "using the good swap function" << std::endl;
    a.swap(b);
  }
};

int main()
{
  double array1[2] = {1.0, 2.0};
  double array2[2] = {3.0, 4.0};

  Map<Vector2d> map1(array1), map2(array2);

  std::swap(map1, map2); // prints nothing, so our overload wasn't called

  // map1.swap(map2); // uncomment for comparison with the good result

  std::cout << "map1:\n" << map1 << std::endl;
  std::cout << "map2:\n" << map2 << std::endl;
}

2010/4/6 Gael Guennebaud <gael.guennebaud@xxxxxxxxx>:
>
> hm, you cannot have partial specializations but you can still have
> overloads, and so the following works well here:
>
> namespace std {
>   template<typename A,typename B> void swap(A& a, B& b) { a.swap(b); }
> };
>
> And of course we can then rely on a small helper struct to leverage partial
> specialization if needed (e.g., to output a nicer compilation error if A and
> B are not Eigen objetcs etc.)
>
> Maybe I'm missing something ?
>
> gael
>
> On Tue, Apr 6, 2010 at 1:03 PM, Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
> wrote:
>>
>> 2010/4/6 joel falcou <joel.falcou@xxxxxx>:
>> > Benoit Jacob wrote:
>> >>
>> >> We already have a swap() that works well in Eigen, depending on two
>> >> template parameters. It has a different calling syntax: it is a member
>> >> function. a.swap(b).
>> >>
>> >
>> > What I tell you is to have a eigen::swap(a,b) free function in eigen
>> > namespace
>> > and promote its use in place of std::swap ;)
>> >
>> > Then you will be able to specialize it properly AND let ADL do its
>> > tricks.
>>
>> Ok, thanks for your suggestion, actually I think I had understood it,
>> but I am coming from a different perspective. I was wondering: can I
>> fix std::swap or do I have to tell the user to do something else? If I
>> have to tell him to do something else, telling him to do a.swap(b); is
>> as good, from my perspective, as telling him to do Eigen::swap(a,b);
>>
>> I think I understand where Boost is coming from: if the namespace
>> boost is "used" instead of namespace std, then the correct swap is
>> automatically used, which is great.
>>
>> But in the case of Eigen, I want it to remain possible to do both:
>> using namespace std;
>> using namespace Eigen;
>>
>> which means that I can't define a global swap() function, as it would
>> conflict  with std::swap ! So I would have to call it ei_swap which
>> would defeat the point (the ability to switch swap functions just by
>> using a different namespace).
>>
>> I guess this is where Eigen is different from Boost and can't do the same.
>>
>> Cheers,
>> Benoit
>>
>> >
>> >
>> >
>>
>>
>
>



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/