Re: [eigen] std::swap doesn't work on Map |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] std::swap doesn't work on Map
- From: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
- Date: Tue, 6 Apr 2010 09:47:10 -0400
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:received:message-id:subject:from:to:content-type :content-transfer-encoding; bh=ne2cUJI5alfTx76PrzIuPJCGlqlhi6yRTJMTeKTMvZE=; b=cAfuFkprumAaIeN+ZvvknRYqFLxDh94ittpNsJKtK74zxuMVOdT14X1CVTXuFw/s7y f6BLiqK+Nj5xd04hnUGRIioh6jHOEicEBs+xN/gwhJZRazjAp8czUhj7wTdovRtBlG9A fa9sa/IECvN/z/26BZlJR4Ns44vKYd0ogQ1+Q=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=OG1OG8zNLV7wXmRKH/dA5pZB4VRJ3v40nnEqftBYtAbG0Q9Mn7PkUnRGmmnICkQwA9 j+9xnTuJSsR6T58xcZaKcd/pB4lmLtABe1P1PXVLRLmtB69agBhSlSRBvnyCCwpWIn9w vumALXFKtuyy0/4IKW4d7tarkKnSMDaD+2dvs=
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
>>
>> >
>> >
>> >
>>
>>
>
>