Carefully select the __ function between the function overload and the default value of the set parameter

Source: Internet
Author: User

--------------------------------------------------------------------------------


Clause 24: Carefully select between function overloading and setting parameter defaults

The reason for confusion about function overloading and setting parameter defaults is that they all allow a function to be invoked in several ways:

void f ();  //f is overloaded
void f (int x);
f ();  //calls F ()
F (a);  //calls F (int)
void g (int x = 0);  //G has a
  //default parameter Value
G ();  Call g (0)
G (a);  //call G
So, when should I use it? The
answer depends on two other questions. First, there really is a value that can be used as the default. Second, how many algorithms to use. In general, if you can select an appropriate default value and only use an algorithm, use the default parameters (see article 38). Otherwise, the function overload is used.
The following is a function that can calculate up to five int maximum values. This function uses--deep breath, see--std::numeric_limits<int>::min (), as the default parameter value. Later, we'll give you a further description of the value, which first gives the code for the function:
int max (int A,
 int B = std::numeric_limits::min (),
 int C = std::numeric_ Limits::min (),
 int d = std::numeric_limits::min (),
 int e = std::numeric_limits::min ())
{
 int temp = a > B? A:B;
 temp = temp > C temp:c;
 temp = temp > D temp:d;
 return temp > E temp:e;
}

The

can be relaxed now. Std::numeric_limits<int>::min () is what the C + + standard library represents in a new method that is already defined in C, which is what the C Int_min macro defines in <limits.h> --The minimum possible value of an int produced by the compiler of your C + + source code. Yes, its syntax deviates from the simplicity of C, but it makes sense to follow the colon and other strange syntax.
Suppose you want to write a function template with a fixed numeric type, and the function that the template produces can print the minimum value represented by the instantiated type. This template can be written like this:
template
void Printminimumvalue ()
{
 cout << is represented as the minimum value of type T;
}

It would be difficult to write this function with <limits.h> and <float.h>, because I don't know what t is, so I don't know if the print int_min or dbl_min, or any other type of value.
To avoid these difficulties, the standard C + + library (see clause 49) in header file <limits>
A class template numeric_limits is defined, and the class template itself defines some static member functions. Each function returns the "instantiate the type of this template" information. That is to say, the function in,numeric_limits<int> returns information about the type int,numeric_limits<double>
The information in the function returned is about the type double. Numeric_limits has a function called Min,min returns the smallest value that can be represented as an "instantiated type", so Numeric_limits<int>::min () returns the smallest value that represents the integer type.
With numeric_limits (like everything else in the standard library, numeric_limits exists in the name space Std; numeric_limits itself in header file <limits>), Writing Printminimumvalue can be as easy as the following:
Template
void Printminimumvalue ()
{
cout << std::numeric_limits::min ();
}

Using a numeric_limits approach to represent "type-dependent constants" looks expensive, but it's not. Because the lengthy statements of the original code are not reflected in the generated target code. In fact, a call to Numeric_limits does not produce any instructions at all. To know what's going on, look below, this is a very simple implementation of numeric_limits<int>::min:
#include
Namespace Std {
inline int numeric_limits<int>::min () throw ()
{return int_min;}
}

Because this function is declared as inline, its invocation is replaced by the function body (see clause 33). It is just a int_min, that is to say, it is simply a #define of the "constants defined by the implementation". So even if the max function at the beginning of this article looks like a function call to each default parameter, it's just another clever way to represent a type-dependent constant (in this case the constant value is int_min). Some highly efficient and ingenious applications such as these are all over the C + + standard library, which can be referenced in clause 49.
Back to the max function: The key point is that the Max calculates the same (inefficient) algorithm, regardless of the number of arguments provided by the caller of the function. There is no place in the function to care about which parameters are "true" and which are the default values, and the default value chosen cannot affect the correctness of the calculation of the algorithm used. This is why scenarios that use default parameter values are feasible.
For many functions, the appropriate default value is not found. For example, suppose you want to write a function to calculate an average of up to 5 int. The default argument cannot be used here because the result of the function depends on the number of arguments passed in: If 3 values are passed, the total is divided by 3, and if 5 values are passed, the total is divided by 5. In addition, if the user does not provide a parameter, no "magic number" can be used as the default, because all possible int can be valid arguments. There is no choice in this case: the function must be overloaded:
Double avg (int a);
Double avg (int a, int b);
Double avg (int a, int b, int c);
Double avg (int a, int b, int c, int d);
Double avg (int a, int b, int c, int d, int e);

Another scenario that must use overloaded functions is to accomplish a particular task, but the algorithm depends on the given input value. This is common for constructors: the "default" constructor constructs an object out of thin air (without input), whereas a copy constructor constructs an object from an existing object:
A class that represents the natural number
Class Natural {
Public
Natural (int initvalue);
Natural (const natural& RHS);

Private
unsigned int value;

void init (int initvalue);
void error (const string& msg);
};

Inline
void Natural::init (int initvalue) {value = InitValue;}
natural::natural (int initvalue)
{
if (InitValue > 0) init (initvalue);
else error ("Illegal initial value");
}

Inline natural::natural (const natural& x)
{init (x.value);}

The constructor entered as int must perform an error check, and the copy constructor is not required, so it requires two different functions to implement, which is the overload. Also note that two functions must assign an initial value to the new object. This causes duplicate code to occur in two constructors, so write a private member function init that contains two constructors common code to solve the problem. This method--calling a common low-level function in overloaded functions to perform certain functions for overloaded functions--is well worth remembering because it is often useful (see article 12).


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.