Why another type of variable can be used as a parameter argument to a constant parameter reference in C ++

void foo(const int& v) { int x = v; std::cout << x; } int main() { unsigned y = 1; foo(y); } 

Passes y instead of const int& legal in C ++

+8
c ++ pass-by-reference
source share
2 answers

There are two factors that make your code work. First, function arguments are allowed up to one implicit conversion, if that allows them to match overload. Secondly, const links can be attached to temporary. What happens here, y implicitly converted to int , creating a temporary copy. v then tied to this temporary.

Consider the following example:

 #include <iostream> void foo(const unsigned int & v) { std::cout << &v << '\n'; } void bar(const int & v) { std::cout << &v << '\n'; } int main() { unsigned int y = 1; std::cout << &y << '\n'; foo(y); bar(y); return 0; } 

You will find that foo(y) prints the same address as y , where bar(y) prints a different address. This will not work with const links. Remarkably, if this were possible, it would mean that changing v cannot actually change y .

+9
source share

Yes, it can be very unpleasant. Compilation is due to an implicit conversion of y to an anonymous temporary int on the calling site, and const int& binding is allowed.

You can defeat this by writing

 void foo(unsigned v) = delete; 

or even

 template<typename Y> void foo(Y v) = delete; 

therefore, all overloads other than the one you explicitly specified are deleted.

+3
source share

All Articles