Re: [eigen] a few updates...

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


2010/12/22 Christoph Hertzberg <chtz@xxxxxxxxxxxxxxxxxxxxxxxx>:
> On 22.12.2010 04:50, Benoit Jacob wrote:
>> * There are 2 remaining places where I haven't fixed
>> const-correctness: the Sparse module (leaving this to Gael) and
>> swap(). I have improved the situation with swap() so that e.g. you
>> can't swap const Matrix's anymore, but there remains a much trickier
>> issue: swapping temporary expression as in:
>>
>>     m.row(i).swap(m.row(j));
>>
>> This is incredibly tricky because C++ doesn't allow one to take
>> non-const references to temporaries, so one has to pass const
>> references and const_cast, which loses the information of whether the
>> expression was const in the first place.
>>
>> There are 2 things we can do here:
>> a) leave it there with c++98 and consider using rvalue references in c++0x mode
>> b) actually there is a crazy aspect of c++98 that allows to fix this
>> problem. As I said, the fundamental issue is that C++ doesn't allow
>> one to take non-const references to temporaries... but that's not
>> entirely true, there's one case in which this is allowed: that's when
>> taking a reference to *this. At least insofar as GCC's behavior is
>> compliant with the spec. So, while the API we have for swap() can't be
>> fixed wrt const-correctness within c++98, this different API:
>>
>>    xpr1.swap() = xpr2.swap()
>>
>> can be made const-correct, by implementing swap() as returning a
>> SwapWrapper<T>, and implementing swap() const as returning a
>> SwapWrapper<const T>.
>
> Seriously this looks a bit ugly ...
> Why would you need a SwapWrapper<const T> anyways?

Sorry, you're right, so what I should have written is: only implement
non-const-qualified swap() method, so that calling it on a const
object fails to compile, while still being possible to call it on a
temporary.

>
> Another possibility would be:
> c) Pass argument to swap() by value if it is a Map/Block-expression.

I tried that, using a enable-if trick to select abstract expressions
vs. plain objects.

The problem is that that doesn't solve the problem at all. By passing
the expression by value, we completely forget its constness, so we
can't prevent doing
  const Expression xpr;
  foo.swap(xpr);

Benoit


> This should never be more than a pointer and a few integers and would
> hopefully be optimized away in most cases.
> Maybe not with the current implementation, when passing sth such as:
>  m.block(...).block(...).transpose().row(...)
> but that could be fixed when solving "direct access type unification".
> Ideally, if every dimension is known at compile-time, passing by value
> would then boil down to just passing a pointer to where the data starts.
>
> Christoph
>
> --
> ----------------------------------------------
> Dipl.-Inf. Christoph Hertzberg
> Cartesium 0.051
> Universität Bremen
> Enrique-Schmidt-Straße 5
> 28359 Bremen
>
> Tel: (+49) 421-218-64252
> ----------------------------------------------
>
>
>



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