简体   繁体   中英

Why I can define a function that differs in the top-level constness of some of its paramters?

Usually functions and classes are declared in header files and defined in some source files for example I have this function which just takes a constant reference to an int and returns bool value deciding whether the parameter is even or odd:

So in my header odd_even.h I have written:

    bool is_even(const int& x); // I used const ref. to avoid copy and unintentional modification of the argument.

And in the source odd_even.cpp :

bool is_even(int& x) { 
    if (x = 1024) // some unintentional assinemnt (==) though modern compilers detect it.
        ; //some statement here
    //x = 1024; // or here another unintentional modification
    return !(x % 2) ? true : false; 
}

And the driver program:

int main(){

    int a{ 17 };
    std::cout << (a) << std::endl;

    std::cout << std::boolalpha << is_even(a) << endl;

    std::cout << (a) << std::endl;

    std::cout << std::endl;
}

As you can see the function is_even definition modifies the argument unintentionally and the client of my program doesn't realize that this function will modify the argument as long as its declaration which takes a const reference to int.

So is there a workaround about this mistake which prevents such mistake?

This should not compile as demonstrated here

C++ allows overload by cv qualifiers when parameter is pointer or reference type, thus it is part of the mangled name.

There is no top-level const here:

bool is_even(const int& x); // 1
bool is_even(int& x); // 2

Above 1 and 2 are totally different signatures: 1 is a function that takes a constant reference to int. Remember the const here is low-level not top-level Also remeber that references don't have top-level const as the fact that they are already constant.

In your example it compiles and runs OK because you are passing a non-const object which is relevant for the signature 2. However if you pass an r-value or then it will fail to link. eg:

std::cout << is_even(77) << std::endl; // link will fail because the 1 is not defined.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM