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.

4.2. GENERIC FUNCTIONS 91<br />

would not compile because the if statement without the parentheses is not a legal expression of<br />

the C ++ grammar. Meanwhile the following stupid implementation:<br />

template <br />

T inline max (T a, T b)<br />

{<br />

if (a > b)<br />

return max(a, b); // Infinite loop !<br />

else<br />

return max(b, a); // Infinite loop !<br />

}<br />

compiles because it does not violate any grammar rule. It obviously results in an infinite loop<br />

but this is beyond the compiler’s responsibility.<br />

So far, the compiler only checked the grammatical correctness of the definition but did not<br />

generate code. If we do not call the template function, the binary will have no trace of our max<br />

function. What happens when we call the generic function and cause their instantiation. The<br />

compiler first checks if the function can be compiled with the given argument type. It can do<br />

it <strong>for</strong> int or double as we have seen be<strong>for</strong>e. What about types that have no ‘>’? For instance<br />

std::complex. Let us try to compile:<br />

std::complex z(3, 2), c(4, 8);<br />

std::cout ≪ ”The maximum of c and z is ” ≪ ::max(c, z) ≪ ’\n’;<br />

The double colons in front of max shall avoid ambiguities with the standard libraries max that<br />

some compilers may include implicitly (as g++ apparently). Our compilation attempt will end<br />

in error like:<br />

Error: no match <strong>for</strong> ≫operator>≪ in ≫a > b≪<br />

Obviously, we cannot call the max function with types that have no “greater than” operator.<br />

In fact, there is no maximum function <strong>for</strong> complex numbers.<br />

What happens when our template function calls another template function which in turn . . . ?<br />

Likewise, these functions are only completely checked at instantiation time. Let us look at the<br />

following program:<br />

#include <br />

#include <br />

#include <br />

#include <br />

int main ()<br />

{<br />

using namespace std;<br />

vector v;<br />

sort(v.begin(), v.end());<br />

}<br />

return 0 ;<br />

Without going into detail, the problem is the same as be<strong>for</strong>e: we cannot compare complex<br />

numbers and thus not sort arrays of it. This time the missing comparison is discovered in<br />

an indirectly called function and the compiler provides you the entire call stack so that you

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

Saved successfully!

Ooh no, something went wrong!