C++ for Scientists - Technische Universität Dresden
C++ for Scientists - Technische Universität Dresden
C++ for Scientists - Technische Universität Dresden
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.