问题
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).
- Does
const &&
bind to all rvalues, specifically prvalues? - Would
const &&
bind to all "moved objects" (xvalues; basically something returned fromstd::move
or similar)?
I can reason that it should, but I don't have any "proof" for this.
- Or conversely, are there cases where an rvalue (prvalue or xvalue) will not bind to
const &&
?- If so, how so?
Note: some clarity from the comments, this question is heavily swayed to classic rvalues, the prvalue value category.
回答1:
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
.
回答2:
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.
来源:https://stackoverflow.com/questions/24943093/does-const-bind-to-all-prvalues-and-xvalues