03.12.2012 Views

C++ for Scientists - Technische Universität Dresden

C++ for Scientists - Technische Universität Dresden

C++ for Scientists - Technische Universität Dresden

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

5.2. PROVIDING TYPE INFORMATION 141<br />

trans_const.cpp:121: Error: ≫const mtl::matrix::dense2D≪ cannot be converted to ≫int≪<br />

in initialization<br />

Obviously, with this trick we will not get an executable binary. But we know more about the<br />

types in our program and can now better solve our problems. In the rare case that the type you<br />

examine is convertible to int, you can take any other type like std::set to which the examined<br />

class is not convertible. To exclude convertibility entirely you can introduce a new type.<br />

After this short excursion into type introspection we know <strong>for</strong> certain that the member ref is a<br />

constant reference. The following happens:<br />

• When we call trans(B) the function’s template argument is instantiated with const dense2D.<br />

• Thus, the return type is transposed view.<br />

• The constructor argument has type const dense2D&.<br />

• Likewise the member has type const dense2D&.<br />

It remains the question why the non-const version of the operator (line 9) is called despite we<br />

refer a constant matrix. The answer is that the constancy of ref does not matter <strong>for</strong> the choice<br />

but whether or not the view object is constant. Thus, we can write:<br />

const tst::transposed view Bt(B);<br />

std::cout ≪ ”Bt(2, 0) = ” ≪ Bt(2, 0) ≪ ’\n’;<br />

This works but it is not very elegant.<br />

A brutal possibility to get the view compiled <strong>for</strong> constant matrices is to cast away the constancy.<br />

The undesired result would be that mutable views on constant matrices enable the modification<br />

of the allegedly constant matrix. This violates so heavily our principles that we do not even<br />

show how the code would read.<br />

Rule<br />

Never cast away const.<br />

In the following we will empower you with very strong methodologies <strong>for</strong> handling constancy<br />

correctly. Every const cast is an indicator <strong>for</strong> a severe design error. As Sutter and Alexandrescu<br />

phrased it “If you go const you never go back.” The only situation where a const cast<br />

is needed by using const-incorrect third-party software, i.e. read-only arguments are passed as<br />

mutable pointers or references. That is not our fault and we have no choice. Un<strong>for</strong>tunately,<br />

there is still a lot of const-incorrect packages around and some of them would take too much<br />

resources to reimplement that we have to live with them. The best we can do is to add an<br />

appropriate API on top of it and avoid working with the original API. This saves ourselves<br />

from spoiling our applications with const casts and restricts the unspeakable const cast to the<br />

interface. A good example of such a layer is ‘Boost::Bindings’ [?] that provides const-correct

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!