C + + function overloading and function matching

Source: Internet
Author: User

C + + Primer notes, sorting out notes about function overloading and function matching.

function overloading
void func (int a); The original function void Func (double a); Correct: Parameter types differ void func (int a, int b); Correct: The number of formal parameters is different int func (int a); Error: Only the return type is different typedef int int32;void func (int32 a); Equivalent to the original function: the formal parameter type is the same as void func (const int a); Equivalent to the original function: the top-level const is ignored by void func (int); Equivalent to the original function: just omitting the formal parameter name

Function overloading is like the following rule:

    • The names are the same, and the formal parameter types are different.
    • No two functions are allowed except for the return type, all of which have the same features.
    • The top const -level parameter cannot be const distinguished from a formal parameter that does not have a top layer.

Where the return type does not compile at the same time, an error occurs, and the type alias, the item layer const , the ellipsis parameter name is only a duplicate declaration, as long as Not defined, the compilation will not error, such as:

Only one of the void func (int a) is defined; void func (const int a) {}
function matching name lookup

The first step in the function matching is the name lookup (name lookup), which determines the candidate function .

Name Lookup has two aspects:

    • General lookup (Normal lookup)
    • Lookup of the argument decision (Argument-dependent Lookup,adl)

All function calls perform a regular lookup, and only the actual arguments of the function include the class type object or pointer/reference to the class type object for the lookup to be determined.

General find

void func (int a);   1namespace n{    //Scope    void func () {}  //2    void func (Double A) {}  //3    ...    void Test1 ()    {        func ();//candidate functions are functions 2 and 3    }    void Test2 ()    {        using:: Func;//Add function 1 to current scope        func ();//Candidate function is function 1    }    ...}

Starting from the local scope called by the function, gradually looking for the called name, and once found, stop looking up and add all the names found to the candidate function.

In addition, the using statement can reference the names of other scopes to the current scope.

ADL Lookup

void Func () {}//1//the namespace of the first argument namespace Name1 {    class T {        friend void func (t&) {}//2    };    void Func (T) {}//3}//the indirect parent class of the second argument is located in the namespace namespace Name00 {    class T00 {        friend void func (int) {}//4    };    void Func () {}//5}//the namespace of the second argument parent class namespace NAME0 {    class t0:public name00::t00 {        friend void func (int) {}//6
   };    void Func () {}//7}//the second argument resides in the namespace namespace Name2 {    class t:public name0::t0 {        friend void func (t&) {}//8
   };    void Func (T) {}//9}void Test () {    name1::t t1;    Name2::t T2;    9 functions are all candidate functions      //1th functions are found in normal lookup//    after 8 functions are all argument-dependent lookup found    func (&T1,T2);}

Start with the first class type parameter and loop through all the class type parameters. For each parameter, enter the scope where the type definition is located (the friend function within the class is also included), and then enter its base class, indirect base class ... Define the scope, find the function with the same name, and join the candidate function.

Note: during a rise in the inheritance system, the rise is not stopped by finding a function of the same name, which is different from regular lookups.

The operator overloads in a class also follow the ADL lookup, and the set of candidate functions includes both member functions and non-member functions.

Namespace n{    class A    {public    :        void operator+ (int A) {}//1    };    void operator+ (a &a, int a) {}//2};void operator+ (a &a, int a) {}//3void Test () {    n::a A;    A + 1; 1, 2, 3 are candidate functions}
Determining viable functions

The second step is to choose the feasible function from the candidate function, the criteria are as follows:

    • The number of formal parameters is equal to the number of arguments supplied by this call
    • The type of each argument is the same as the corresponding parameter type, or can be converted to a form parameter type
The following is the candidate function void func (int a, double b) {}//feasible function void func (int a, int b) {}//feasible function: argument can convert form parameter type int func (int A, double b) {}//feasible function void func (int a) {}//non-viable function: parameter number mismatch void func (int a, int b[]) {}//non-viable function: argument cannot convert form parameter void Test () {    func (1, 0.1);}
Finding the best match

Select the most matching function from the feasible function, and if there are multiple parameters, the best match condition is:

    • The match for each argument of the function is not inferior to that required by other viable functions.
    • A match with at least one argument is better than the match provided by other viable functions.

Otherwise, a two semantic invocation error occurs.

feasible function void func (int A, float b) {}void func (int a, int b) {}void test () {    func (1, 0.1);//Two semantic error: double conversion to int and to Floa The conversion of T is as good as    func (1, 1);//Call void func (int a, int b)}

To determine the best match, the conversion level of the argument type to the formal parameter type is as follows:

    1. Exact match:
      • The argument type is the same as the formal parameter type.
      • An argument is converted from an array type or function type to a corresponding pointer type.
      • Add the top layer to the argument const or delete the top layer from the actual argument const .
    2. The const matching implemented by the transformation.
    3. A match implemented by type promotion.
    4. A match implemented by an arithmetic type conversion or a pointer transformation.
    5. A match implemented by a class type conversion.

In general, this phase does not exist with more than two exact matches, since two exact matches are inherently equivalent, and when defining overloaded functions, the compiler may report a redefinition error.

Pick a few key points to say in detail.

Matching of pointer conversion implementations

    • 0 or nullptr can be converted to any pointer type.
    • T *can be converted into void * , const void * converted into const void* .
    • The conversion of a derived class to a base class type.
    • The parameter types of the function and function pointers must match exactly.

Matching of class type conversion implementations

Two types that provide the same type conversions will produce a two semantic problem.

struct b;struct a{    A () = default;    A (const b&);    Convert a B to a};struct b{    operator A () const;//Convert a B to a}; A f (const a&); b b; A = f (b); Ambiguity error: F (b::operator A ()) or F (a::a (const b&)) A a1 = f (B.operator a ()); Correct: Use the type of B conversion operation a a2 = f (A (B)); Correct: Use A's constructor

A class that defines a constructor or type conversion operator that has multiple parameters that are arithmetic types also produces a two semantic problem.

struct a{    A (int = 0);    A (double);    operator int () const;    operator double () const; void f (long double); A a;f (a); Ambiguity error: F (a::operator Int ()) or F (A::operator double ())? Long L; A A2 (L); Ambiguity error: a::a (int) or a::a (double)? Short S; A A3 (s); Correct: Use A::A (int)

When we use two user-defined type conversions, a standard type conversion determines exactly which of the best matches if there is a standard type conversion before or after the conversion function.

Section reference: http://particle128.com/posts/2013/11/name-lookup.html

Original address: Http://simpleyyt.github.io/2016/12/17/function-overload-and-match

C + + function overloading and function matching

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.