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

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

92 CHAPTER 4. GENERIC PROGRAMMING<br />

can trace back the error. Please try to compile this example on different compilers at your<br />

availability and see if you can make any sense out of the error messages.<br />

If you run into such lengthy error message 1 DON’T PANIC! First, look at the error itself<br />

and take out what is useful <strong>for</strong> you, e.g. missing “operator>” or something not assignable,<br />

i.e. missing “operator=” or something const that should not. Then find in the call stack your<br />

innermost code that is the part of your program where you call somebody else’s template<br />

function. Stare <strong>for</strong> a while at this and its preceding lines because this is the most likely place<br />

where the error is made. Does a type of the template function function’s argument is missing<br />

an operator or function as mentioned in the error? Do not get scared away from this, often<br />

the problem is much simpler than it seems from the never-ending error message. From our<br />

experience, most errors in template functions one can find faster than run-time errors.<br />

Another question we have not answered so far is what happens if we use two different types:<br />

unsigned u1= 2;<br />

int i= 3;<br />

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

The compiler tell us — this time briefly — something like<br />

Error: no match <strong>for</strong> function call ≫max(unsigned int&, int)≪<br />

Indeed, we assumed that both types are the same. Now can we write a template function with<br />

two template parameters? Of course, we can. But that does not help us much here because we<br />

would not know what return type the function had.<br />

There are different options. First we could add a non-templated function like:<br />

int inline max (int a, int b) { return a > b ? a : b; }<br />

This can be called with mixed types and the unsigned argument would be implicitly converted<br />

into an int. But what would happen if we also add a function <strong>for</strong> unsigned?<br />

int max(unsigned a, unsigned b) { return a > b ? a : b; }<br />

Shall the int be converted into an unsigned or vice versa? The compiler does not know and will<br />

complain about this ambibuity.<br />

At any rate, adding non-templated overloads to the templated implemention is far from being<br />

elegant nor productive. So, we remove all non-templated overloads and look what we can do in<br />

the function call. We can explicitly convert one argument to the type of the other:<br />

unsigned u1= 2;<br />

int i= 3;<br />

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

Now max is called with two ints. Another option is specifying the template type explicitly in<br />

the function call:<br />

unsigned u1= 2;<br />

int i= 3;<br />

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

1 The longest we have heard off was 18MB what corresponds to about 9000 pages of text.

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

Saved successfully!

Ooh no, something went wrong!