Does `const &&` bind to all prvalues (and xvalues)?

坚强是说给别人听的谎言 提交于 2019-12-19 17:34:10

问题


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 from std::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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!