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.

146 CHAPTER 5. META-PROGRAMMING<br />

trans_const.cpp:96: Error: Invalid application of ≫sizeof≪ on incomplete type<br />

≫boost::STATIC_ASSERTION_FAILURE≪<br />

If you see an error message with “STATIC ASSERTION” in it, do not think about the message<br />

itself (it is meaningless) but look at the source code line that caused this error and hope that<br />

the author of the assertion will provide more in<strong>for</strong>mation in a comment.<br />

When we try to compile our test with the assertion we will see that trans(A) compiles but<br />

not trans(B). The reason is that ‘const dense2D’ is considered different from ‘dense2D’ in<br />

template specialization so that it is still considered non-matrix. The good new is that we do not<br />

need to double our specializations <strong>for</strong> mutable and constant types but we can write a partial<br />

specialization <strong>for</strong> all constant arguments:<br />

template <br />

struct is matrix<br />

: is matrix {};<br />

Note that BOOST STATIC ASSERT is a macro and does not understand C ++. This manifests in<br />

particular if the argument contains one or more commas. Than the preprocessor will interpret<br />

this as multiple arguments <strong>for</strong> the macro and get confused. This confusion can be avoided<br />

by enclosing the argument of BOOST STATIC ASSERT with two enclosing parentheses as we did<br />

in the example (although it was not necessary here). Despite the double parentheses and the<br />

rather arbitrary error message, static assertions are very useful to increase reliabily. The next<br />

C ++ standard will provide static assertions in the language like:<br />

template <br />

class transposed view<br />

{<br />

static assert(is matrix::value, ”transposed view requires a matrix as argument”);<br />

// ...<br />

};<br />

As the reader can see, the integration into the language overcomes the be<strong>for</strong>e-mentioned deficiencies<br />

of the macro implementation.<br />

Useful are meta-functions to remove something from a type if exists, e.g. remove const trans<strong>for</strong>ms<br />

const T into T and non-constant types remain unchanged. Note that this only removes the<br />

constancy of entire types not that of template arguments, e.g., in vector the constancy<br />

of the arguments is not removed.<br />

Dually, meta-functions can add something to a type:<br />

typedef typename boost::add reference::type ref type;<br />

It would be shorter to just add an & but this is easily overseen in longer type definitions. More<br />

importantly, if some trait returns already a reference then it is an error to add another one. The<br />

meta-function adds the reference only to types that are no references yet. To adding const to a<br />

type we find it more concise without the meta-function:<br />

typedef typename some trait::type const const type;<br />

If the type trait returns already a constant type, the second const will be ignored.<br />

The widest functionality in the area of meta-programming provides the Boost Meta-Programming<br />

Library (MPL) [GA04]. The library implements most of the STL algorithms (§ 4.9) and also

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

Saved successfully!

Ooh no, something went wrong!