Main problem:
'hello'
is a character literal that denotes an integer, if it is at all accepted (how many characters you can use depends on the compiler). At one time it was used to generate magic numbers that e.g. denoted file types. For example, in old DOS a file that started with the characters MZ was an executable, and the Windows command interpreter, although not Windows Explorer, still recognizes that silly magic:
[H:\dev\test\0119]
> echo MZ >blah.txt
[H:\dev\test\0119]
> blah.txt
This version of H:\dev\test\0119\blah.txt is not compatible with the version of Windows you're running. Check your computer's system informa
tion and then contact the software publisher.
[H:\dev\test\0119]
> _
In old C code that number would perhaps be denoted by an integer constant like 'ZM'
.
Now, starting with your definition …
template< typename T >
T foo(T a, T b) {
if (a<b) {
return b;
}
return a;
}
Let me first rewrite it to a form I’m more comfortable with:
template< class Type >
auto foo( Type const a, Type const b)
-> Type
{ return (a<b? b : a); }
I do this rewrite up front so that that aspect can be ignored in the following.
Regardless of form it has a problem when the actual arguments are of different types, e.g. in the call foo( 3, 4.5 )
. Then argument type deduction will fail, so that the type must be specified explicitly, foo<double>( 3, 4.5 )
. How to avoid that?
For numeric types you can deal with that like this:
template< class Type1, class Type2 >
auto foo( Type1 const a, Type2 const b )
-> decltype( a + b )
{ return (a<b? b : a); }
Now you want to call it with string literals as arguments. They will be deduced as type char const*
, and then the a + b
expression will not compile. For you can't add pointers.
For that matter, the a<b
expression would yield an probably unintended result, just comparing the pointer values instead of a lexicographic compare of the strings.
One solution is then to provide an overload of the function:
auto foo( char const* const a, char const* const b)
-> char const*
{ return (strcmp( a, b ) < 0? b : a); }
Then you can call it like foo( "bravo", "alpha" )
.
Disclaimer: all C++ code untouched by compilers’ hands.