Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

universal reference vs const reference priority?

When I consider the two following overloads:

template <class... T> void f(const T&... x);
template <class T> void f(const T& x);

I have the guarantee that f(x) will always call the second function and will never lead to an ambiguity. In a sense the second version is universally prioritized compared to the first one for one argument whatever its type is.

Now consider the situation where there is a universal reference and a const reference versions of a function:

template <class T> void f(T&& x);
template <class T> void f(const T& x);

My question is: is their a universal priority between these two functions regardless of the type of x (r-value reference, reference, cv-qualifiers, pointer...) like in the previous case? (and if yes, what is the priority ?)

like image 509
Vincent Avatar asked Aug 16 '13 02:08

Vincent


People also ask

What is the difference between const reference and reference?

A const reference is actually a reference to const. A reference is inherently const, so when we say const reference, it is not a reference that can not be changed, rather it's a reference to const. Once a reference is bound to refer to an object, it can not be bound to refer to another object.

Does const reference extend lifetime?

You are not questioning why const references are allowed to bind to temporaries, but merely why they extend the lifetime of those temporaries. If the lifetime of the temporary returned by bar() were not extended, then any usage of a (exemplified by the line (1)) would lead to undefined behavior.

What are the differences between passing a parameter by reference and by constant reference?

The important difference is that when passing by const reference, no new object is created. In the function body, the parameter is effectively an alias for the object passed in. Because the reference is a const reference the function body cannot directly change the value of that object.

When should you use a const reference parameter?

Pass Using Const Reference in C++ Now, we can use the const reference when we do not want any memory waste and do not change the variable's value. The above code will throw a compile error as num = num +10 is passed as a const reference.


1 Answers

There is not a universal priority between these two functions. They compete equally in the overload resolution algorithm. In general the so-called "universal reference" wins unless const T& is an exact match, and there the const T& wins.

struct A {};

int
main()
{
    f(std::declval<A>());  // calls f<A>(A&&), #1
    f(std::declval<const A>());  // calls f<const A>(const A&&), #1
    f(std::declval<A&>());  // calls f<A&>(A&), #1
    f(std::declval<A&&>());  // calls f<A>(A&&), #1
    f(std::declval<const A&&>());  // calls f<const A>(const A&&), #1
    f(std::declval<const A&>());  // calls f<A>(const A&), #2
}

Good advice is to never overload like this.

like image 79
Howard Hinnant Avatar answered Sep 18 '22 15:09

Howard Hinnant