Overloading on const and volatile- why does it work by reference?

后端 未结 2 745
迷失自我
迷失自我 2020-12-19 11:23

I have the code:

#include \"stdafx.h\"
#include 

using namespace std;


void func(const int& a)
{
    std::cout << \"func(const)\"         


        
相关标签:
2条回答
  • 2020-12-19 12:00

    The issue is that the top level const and/or volatile are ignored in overload resolution. So

    void foo(const int);
    

    is exactly the same as

    void foo(int);
    

    and similarly for volatile. This is a language rule, and it makes sense since the arguments are passed by value. On the other hand, reference to const/volatile or pointer to const/volatile have a different meaning: you are not allowed to call non-const/volatile methods on what they refer to or point to. Here, the const volatile are not top level.

    void foo(int& i);       // can modify what i refers to, and this has effects outside of foo.
    void foo(const int& i); // cannot modify what i refers to
    

    The two above declarations have very different semantics, so the language makes them distinct concerning overload resolution.

    0 讨论(0)
  • 2020-12-19 12:10

    Perhaps it is useful to take a step back from the functions and just look at the use-cases themselves.

    First, we will define an integer and a constant integer for use in our examples:

    int       anInt     = 1;
    const int aConstInt = 1;
    

    Next, we take a look at what happens when using these variables to set the values of other integers and constant integers:

    int       a = anInt;     // This works, we can set an int's value
                             //  using an int
    int       b = aConstInt; // This works, we can set an int's value
                             //  using a const int
    const int c = anInt;     // This works, we can set a const int's value
                             //  using an int
    const int d = aConstInt; // This works, we can set a const int's value
                             //  using a const int
    

    As you can see, there is no way to resolve which overload of a function to select based on behavior (a const int can be accepted by both an int and a const int, and likewise an int can be accepted by both an int and a const int).

    Next, we shall take a look at what happens when pass the first set of variables to references:

    int& a = anInt;     // This works because we are using a
                        //  non-constant reference to access a
                        //  non-constant variable.
    int& b = aConstInt; // This will NOT work because we are
                        //  trying to access a constant
                        //  variable through a non-constant
                        //  reference (i.e. we could
                        //  potentially change a constant
                        //  variable through the non-const
                        //  reference).
    
    const int& c = anInt;     // This works because we are using a
                              //  constant reference (i.e. "I cannot
                              //  try to change the referenced
                              //  variable using this reference") to
                              //  a non-constant variable.
    const int& d = aConstInt; // This will work because we are trying
                              //  to access a constant variable 
                              //  through a constant reference.
    

    As you can see, there is some useful behavior that can be had out of distinguishing between an int reference and a const int reference (i.e. disallowing creation of a non-constant reference when a constant reference type is expected).

    0 讨论(0)
提交回复
热议问题