|Re: [eigen] MatrixBase::swap -- why const?|
[ Thread Index |
| More lists.tuxfamily.org/eigen Archives
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] MatrixBase::swap -- why const?
- From: Patrick Mihelich <patrick.mihelich@xxxxxxxxx>
- Date: Fri, 5 Jun 2009 02:25:30 -0700
- 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:message-id:subject:from:to:content-type; bh=0u7XCpjeB7c7ROeKsBOyucY2nG+8eC6hwZtuXY08X/8=; b=ww/XvPptf5yNkRnReQzrG5MKmjmJ6+CRrwt5VV5fxnb+T6p1RGX7oxioE9Zy6EmiRz FioJsEFW6klr8tt445LaLBBjss4lRDK2zkiZzG4kLKFqOGSy6VUwq0QfLFYQIvr3ElZ9 b1k/FIq6ItA+g6FLzOWx9jW0HWu2c5fVUNXjQ=
- 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; b=eHKcSO5LCGlmM4dKdesdAKdaytBXomufTvBQefL0wYPcu4aPc4ZluMQjmv7LLReyhQ Nu0C8svEBzLXtxLX/g62OGUMzkvFObMibYQ4zDnXTG9jjPfYEHIk3m4B2JCEhwfb+n78 nFpVrBA+/fgMEk8YmXciMTryN/dVBdqXHs4V0=
the problem is that c++ doesn't seem to allow to pass a non-constant
reference to a temporary.
Right. This problem is solved by rvalue references in C++0x. I believe what you really want is:
void swap(MatrixBase<OtherDerived>&& other)
which will bind to temporaries as well as lvalue references. Similarly for lazyAssign, and anywhere else you're currently abusing const_casts to support temporaries. Of course rvalue references are only supported by the very latest compilers :(
Using const reference arguments and const_cast is the simplest solution, but has some serious drawbacks. It is indeed a breach of contract. It works in all the cases you want it to work, but also ones you don't!
It's possible to emulate the "move semantics" of rvalue references in pure C++03 to some degree, and there's been a lot of discussion on the Boost mailing list about this. If you want some inspiration, or a headache, check out at least the first couple sections of the docs for the proposed Boost.Move macros library. The BOOST_ENABLE_MOVE_EMULATION and BOOST_RV_REF expand to the idiomatic C++0x solution (if possible), or to a close C++03 approximation. A drawback to emulation is you'd need to use swap on temporaries like this:
matrix.row(i).swap( move(matrix.row(j)) )
which is more verbose with the "move" call but makes permission to modify the object explicit.
Another option is to stick with the current solution but use rvalue refs when available:
#define EIGEN_RV_REF(type) type&&
#define EIGEN_RV_REF(type) const type&
void swap( EIGEN_RV_REF(MatrixBase<OtherDerived>) other )
That way at least the early adopters can have their type safety. Probably another macro is needed to deal with the const_casting; I'm too tired to work out the full details.
swap() for heterogeneous types makes me a bit uneasy, but maybe it is OK. I'll have to take a closer look later.