Wednesday, March 28, 2012

String arguments in templates

Well, well, well.
Up to this point, you should have a minimal idea of templates. Of course, there are some chapter
that you didn't understand yet or you didn't take the whole idea that I was trying to teach.

But don't worry, you just need reviews like this post to understand that some of the titles I made
are of huge interest and even, indeed, more complex.

Here there's an example that show that the chapter, argument deduction, is more complex as it
seems and we don't have to take it as if nothing because even with the string type we can get
much mistakes as you think.

#include <string>
// note: reference parameters
template <typename T>
inline const T& max (const T& a, const T& b){
     return a < b ? b : a;
}
int main(){
     std::string s;
     ::max("bye","cya"); // OK: same type
     ::max("hello","bye"); // ERROR: different types
     ::max("chau",s); // ERROR: different types
}


First look, you may think, what the hell is happening here, how it doesn't work?, but if you take long
time and read the compiler you'll that is an error about types.

First off, remember that string is a C++ type and when you declare some thing like "this (with commas)" you are not really creating an string if not that is an char*. Thus, max(), is not
calling the function max with string's type if not that are char's.

Beside, we have to notice, in order to see the error, that the problem becomes from pass arguments
as reference (&) because without this we didn't get error from first and second call.
That's it because without pass by reference the type pass it is const char*. On the other hand, calling
by reference, we are passing the following type. char const[3] where this number is the size of
the string.

This makes that two strings of different sizes makes an error like in the second call where
"hello" is 4 and "bye" is 3(insist, all this is by argument deduction).

There are many forms to solve this problem like be sure that strings are strings(for instance, string("bye") ) but I want to handle it with templates; it's not as elegant as I'd like but this is it.


template <typename T, int N, int M>
inline T const* max (const T (&a)[N], const T (&b)[M]){
     return a < b ? b : a;
}




No comments:

Post a Comment