Saturday, February 18, 2012

Overloading: calls by reference and by value

In this chapter you would understand the significance defining functions types.

By the way, it's a good idea to pass all arguments by references whenever you don't have to modify any parameter. In fact, pass by references is much efficient.

Example:

#include <iostream>
#include <cstring>
// maximum of two values of any type (call-by-reference)
template <typename T>
inline T const& max(T const& a, T const& b) {
     std::cout << "call-by-reference, 2 arguments" << std::endl;
     return a < b ? b : a;
}
// maximum of two C-strings (call-by-value)
inline char const* max(char const* a, char const* b) {
     std::cout << "call-by-value" << std::endl;
     return (std::strcmp(a, b) < 0) ? b : a;
}
// maximum of three values of any type (call-by-reference)
template <typename T>
inline T const& max(T const& a, T const& b, T const& c) {
     std::cout << "call-by-reference, 3 arguments" << std::endl;
     return max(max(a, b), c); // error, if max(a,b) uses call-by-value
}

int main() {
     ::max(1, 2, 3);// OK
     std::cout << std::endl;
     
     const char* s1 = "surpring";
     const char* s2 = "-";
     const char* s3 = "code";
     ::max(s1, s2, s3);// ERROR, warning: returning reference to temporary
     std::cout << std::endl; 
     
     ::max(*s1, *s2, *s3);//works good! (by reference)
     std::cout << std::endl; 
}
::max(s1, s2, s3);// ERROR, warning: returning reference to temporary
This line is given an error/warning because call to the non-template function andhis parameters expected a value not a reference.

We may fix up it changing the definition to const char* const&. (There are others)

If we switch the order the compiler might take another function, for example, if the order is the bellow:

template <typename T>
inline T const& max(T const& a, T const& b) {

template <typename T>
inline T const& max(T const& a, T const& b, T const& c) {
inline char const* max(char const* a, char const* b) {

Now, with this call ::max(s1, s2, s3); we won't have the warning but, look out, because at this form we aren't using return (std::strcmp(a, b) < 0) ? b : a; .


For the moment, as a rule of thumb you always have all
overloaded versions of a function declared before the function is called.

 

No comments:

Post a Comment