The C++ standard defines the following functions deleted;
template <class T>
void ref(const T&&) = delete;
template <class T>
void cref(const T&&) = delete;
This is to aid in ensuring that the functions are not misused by disallowing them from binding to temporary values (rvalues).
const &&
bind to all rvalues, specifically prvalues?const &&
bind to all "moved objects" (xvalues; basically something returned from std::move
or similar)?I can reason that it should, but I don't have any "proof" for this.
const &&
?
Note: some clarity from the comments, this question is heavily swayed to classic rvalues, the prvalue value category.
What is const (constant)? Const (constant) in programming is a keyword that defines a variable or pointer as unchangeable. A const may be applied in an object declaration to indicate that the object, unlike a standard variable, does not change.
The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable—just that the variable identifier cannot be reassigned. For instance, in the case where the content is an object, this means the object's contents (e.g., its properties) can be altered.
1. fixed and invariable; unchanging. 2. continual or continuous; incessant.
The const keyword specifies that a variable's value is constant and tells the compiler to prevent the programmer from modifying it. In C, constant values default to external linkage, so they can appear only in source files.
T const&&
can bind to rvalues of type T
or const T
.
From 8.5.3 [dcl.init.ref] paragraph 5:
5 - A reference to type "cv1 T1" is initialized by an expression of type "cv2 T2" as follows: [...]
— Otherwise, [...] the reference shall be an rvalue reference. [...]
— If the initializer expression
— is an xvalue, class prvalue, array prvalue or function lvalue and "cv1 T1" is reference-compatible with "cv2 T2" [...] then the reference is bound to the value of the initializer expression [...]
If the initializer expression is a prvalue of non-class type, then a temporary copy is created for reference binding (ibid).
Reference-compatibility is defined in 8.5.3p4; it requires a same-or-base-class relationship and same-or-greater cv qualification.
So for an rvalue to bind to T const&&
, its cv-qualification must be no greater than const
.
I want to add some empirical evidence here supporting the answer.
template <class T>
void ref(T&) {}
template <class T>
void ref(volatile T&) {}
template <class T>
void ref(volatile const T&) {}
template <class T>
void ref(const T&) {}
template <class T>
void ref(const T&&) = delete;
// xvalues
int&& ax();
const int&& bx();
volatile int&& cx();
volatile const int&& dx();
// prvalues
int ap();
const int bp();
volatile int cp();
volatile const int dp();
void test()
{
ref(ax());
ref(bx());
ref(cx());
ref(dx());
ref(ap());
ref(bp());
ref(cp());
ref(dp());
}
All the calls to ref
in this case fail to compile, both xvalues and prvalues with the cv-qualified variations; msvc, gcc and clang all fail the compilation with the appropriate "attempting to reference a deleted function" error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With