45

I was wondering what use an rvalue reference member has

class A { // ... // Is this one useful? Foo &&f; }; 

Does it have any benefits or drawbacks compared to an lvalue reference member? What is a prime usecase of it?

3
  • @GMan I don't know why that is better than just saying template<typename T> struct acw { T &t; acw(T &&t):t(t) {} template <typename U> operator U() { return static_cast<U>(std::forward<T>(t)); } }. What do you gain by having the member t an rvalue reference? BTW, I think n3225 says that a defaulted copy constructor is defined as deleted if you have any rvalue reference members. So you still cannot copy a auto_cast_wrapper<nonlref> but only move it :) Commented Jan 23, 2011 at 20:37
  • Nothing, I just mean I used it lol. And hm, good to know. I'll have to fix it later. Commented Jan 23, 2011 at 20:46
  • @GMan Ohh i see now! Thanks for showing, I think it's some interesting tool to use. Commented Jan 23, 2011 at 20:54

4 Answers 4

29

I've seen one very motivating use case for rvalue reference data members, and it is in the C++0x draft:

template<class... Types> tuple<Types&&...> forward_as_tuple(Types&&... t) noexcept; 

Effects: Constructs a tuple of references to the arguments in t suitable for forwarding as arguments to a function. Because the result may contain references to temporary variables, a program shall ensure that the return value of this function does not outlive any of its arguments. (e.g., the program should typically not store the result in a named variable).

Returns: tuple<Types&&...>(std::forward<Types>(t)...)

The tuple has rvalue reference data members when rvalues are used as arguments to forward_as_tuple, and otherwise has lvalue reference data members.

I've found forward_as_tuple subsequently helpful when needing to catch variadic arguments, perfectly forward them packed as a tuple, and re-expand them later at the point of forwarding to a functor. I used forward_as_tuple in this style when implementing an enhanced version of tuple_cat proposed in LWG 1385:

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1385

Sign up to request clarification or add additional context in comments.

3 Comments

Could you explain how the rvalue lifetime is managed in this case? Is rvalue destruction is somehow extended until the "later" point when the rvalue is used?
thanks for your your answer and explanation. The question came up what the requirement "Because the result may contain references to temporary variables, a program shall ensure that the return value of this function does not outlive any of its arguments." implies to a program. Does a snippet like this has undefined behavior? { auto x = forward_as_tuple(0); }, because it violates the shall-requirement in the effects section? Why is such a requirement needed? Is a tuple containing stale references not allowed to be destructed?
The client of forward_as_tuple must ensure that the result is "consumed" prior to the sequence point. First examples of its use are found in: open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3059.pdf but in this document the function is called pack_arguments instead of forward_as_tuple. The use in N3059 shows the tuple of references being created, passed on to another function, consumed (used), and destructed, in that order.
15

According to Stephan T. Lavavej, rvalue reference data members have no use.

[at 31:00] The thing I've seen programmers do when they get hold of rvalue references is that, they start to go a little crazy, because they're so powerful. They start saying "Oh, I'm gonna have rvalue reference data members, I'm gonna have rvalue reference local variables, I'm gonna have rvalue reference return values!" And then they write code like this: [...]

13 Comments

It will be about 10 years before we work out how to use rvalue references correctly.
@7vies: The primary reason programmers are confused about rvalue references is because they are already confused about rvalues.
@Martin: True, and in ten years the C++ Committee will be just about ready to release C++2x which will probably have some completely new type of expression that we'll have to learn... ξvalues, perhaps.
@James: I sure hope so. Being stuck with only five different value categories forever would be kinda boring, wouldn't it?
For whom may want to know, he said that at 31:00 in the video.
|
3

Just thinking out loud here, but wouldn't it have a use in functors? The constructor is often used for "currying", binding some parameters in advance, before the actual function call.

So in this context, the class member is just a staging ground (or a manually implemented closure) for the upcoming function call, and I see no reason why a rvalue reference wouldn't be meaningful there.

But in "regular" non-functor classes, I don't see much point.

7 Comments

How in this case an rvalue reference is better than a const & (or just a normal reference if you need to modify it)?
For the same reason you might otherwise want to pass a rvalue ref to a function: to be able to move from it.
@jalf: Then just pass by value and move from the parameter to the member.
@Fred: presumably the entire point would be to avoid having to pass by value (and perhaps the parameter type isn't copyable, but it may be movable)
@jalf: I'm not sure I get your point. Pass by value means moving if the argument is an rvalue. Related FAQ entry
|
3
class A { // ... // Is this one useful? Foo &&f; }; 

In this specific case, there is no reason to use an rvalue reference. It doesn't buy you anything you couldn't have done before.

But you may want to define data members with parameterized types. std::tuple is going to support lvalue and rvalue reference data members, for example. This way it allows you to codify an expression's value category which might come in handy for "delayed perfect forwarding". The standard draft even includes a function template of the form

template<class Args...> tuple<Args&&...> pack_arguments(Args&&...args); 

But I'm honestly not sure about its usefulness.

1 Comment

This post explains one possible use of forward_as_tuple or pack_arguments: cpptruths.blogspot.com/2012/06/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.