Does it make sense for a function to return a rvalue referenceIs returning by rvalue reference more efficient?What should main() return in C and C++?Advantages of using forwardClasses, Rvalues and Rvalue ReferencesImage Processing: Algorithm Improvement for 'Coca-Cola Can' RecognitionWhy should I use a pointer rather than the object itself?Does this rvalue signature pattern make sense?Replacing a 32-bit loop counter with 64-bit introduces crazy performance deviationsReturn value or rvalue reference?Rvalue and Lvalue Referencesrvalue reference or forwarding reference?

What if the end-user didn't have the required library?

Pressure inside an infinite ocean?

Emotional immaturity of comic-book version of superhero Shazam

What exactly are the `size issues' preventing formation of presheaves being a left adjoint to some forgetful functor?

Word meaning as function of the composition of its phonemes

ZSPL language, anyone heard of it?

Is there an idiom that support the idea that "inflation is bad"?

How to make a chinese doggy bag?

Appropriate certificate to ask for a fibre installation (ANSI/TIA-568.3-D?)

Why did the Apollo 13 crew extend the LM landing gear?

exec command in bash loop

What is the solution to this metapuzzle from a university puzzling column?

What are the differences between credential stuffing and password spraying?

Do I add my skill check modifier to the roll of 15 granted by Glibness?

Has the Hulk always been able to talk?

Why do people keep telling me that I am a bad photographer?

What are the advantages of luxury car brands like Acura/Lexus over their sibling non-luxury brands Honda/Toyota?

Word for Food that's Gone 'Bad', but is Still Edible?

In Russian, how do you idiomatically express the idea of the figurative "overnight"?

Where is the documentation for this ex command?

Did we get closer to another plane than we were supposed to, or was the pilot just protecting our delicate sensibilities?

Did the manned NASA capsules rotate during descent?

What was the first sci-fi story to feature the plot "the humans were the monsters all along"?

Chapter style minimal design



Does it make sense for a function to return a rvalue reference


Is returning by rvalue reference more efficient?What should main() return in C and C++?Advantages of using forwardClasses, Rvalues and Rvalue ReferencesImage Processing: Algorithm Improvement for 'Coca-Cola Can' RecognitionWhy should I use a pointer rather than the object itself?Does this rvalue signature pattern make sense?Replacing a 32-bit loop counter with 64-bit introduces crazy performance deviationsReturn value or rvalue reference?Rvalue and Lvalue Referencesrvalue reference or forwarding reference?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








10















What would be a valid use case for a signature like this:



T&& foo();


Or is the rvalue ref only intended for use as argument?



How would one use a function like this?



T&& t = foo(); // is this a thing? And when would t get destructed?









share|improve this question

















  • 3





    std::move comes to mind. It certainly returns T&&. Edit : std::optional::value also has an T&& overload. Edit 2 : It also has a const T && overload, though I'll admit I don't understand the meaning.

    – François Andrieux
    3 hours ago







  • 1





    @FrançoisAndrieux the std::get family of functions, too.

    – Brian
    3 hours ago






  • 1





    See this answer.

    – lubgr
    3 hours ago

















10















What would be a valid use case for a signature like this:



T&& foo();


Or is the rvalue ref only intended for use as argument?



How would one use a function like this?



T&& t = foo(); // is this a thing? And when would t get destructed?









share|improve this question

















  • 3





    std::move comes to mind. It certainly returns T&&. Edit : std::optional::value also has an T&& overload. Edit 2 : It also has a const T && overload, though I'll admit I don't understand the meaning.

    – François Andrieux
    3 hours ago







  • 1





    @FrançoisAndrieux the std::get family of functions, too.

    – Brian
    3 hours ago






  • 1





    See this answer.

    – lubgr
    3 hours ago













10












10








10


2






What would be a valid use case for a signature like this:



T&& foo();


Or is the rvalue ref only intended for use as argument?



How would one use a function like this?



T&& t = foo(); // is this a thing? And when would t get destructed?









share|improve this question














What would be a valid use case for a signature like this:



T&& foo();


Or is the rvalue ref only intended for use as argument?



How would one use a function like this?



T&& t = foo(); // is this a thing? And when would t get destructed?






c++






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 3 hours ago









Martin B.Martin B.

792313




792313







  • 3





    std::move comes to mind. It certainly returns T&&. Edit : std::optional::value also has an T&& overload. Edit 2 : It also has a const T && overload, though I'll admit I don't understand the meaning.

    – François Andrieux
    3 hours ago







  • 1





    @FrançoisAndrieux the std::get family of functions, too.

    – Brian
    3 hours ago






  • 1





    See this answer.

    – lubgr
    3 hours ago












  • 3





    std::move comes to mind. It certainly returns T&&. Edit : std::optional::value also has an T&& overload. Edit 2 : It also has a const T && overload, though I'll admit I don't understand the meaning.

    – François Andrieux
    3 hours ago







  • 1





    @FrançoisAndrieux the std::get family of functions, too.

    – Brian
    3 hours ago






  • 1





    See this answer.

    – lubgr
    3 hours ago







3




3





std::move comes to mind. It certainly returns T&&. Edit : std::optional::value also has an T&& overload. Edit 2 : It also has a const T && overload, though I'll admit I don't understand the meaning.

– François Andrieux
3 hours ago






std::move comes to mind. It certainly returns T&&. Edit : std::optional::value also has an T&& overload. Edit 2 : It also has a const T && overload, though I'll admit I don't understand the meaning.

– François Andrieux
3 hours ago





1




1





@FrançoisAndrieux the std::get family of functions, too.

– Brian
3 hours ago





@FrançoisAndrieux the std::get family of functions, too.

– Brian
3 hours ago




1




1





See this answer.

– lubgr
3 hours ago





See this answer.

– lubgr
3 hours ago












3 Answers
3






active

oldest

votes


















7














For a free function it doesn't make much sense to return a rvalue reference. If it is a non-static local object then you never want to return a reference or pointer to it because it will be destroyed after the function returns. It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not.



One thing that can greatly benefit from returning an rvalue reference is a member function of a temporary object. Lets say you have



class foo

std::vector<int> bar
public:
foo(int n) : bar(n)
std::vector<int>& get_vec() return bar;
;


If you do



auto vec = foo(10).get_vec();


you have to copy because get_vec returns an lvalue. If you instead use



class foo

std::vector<int> bar
public:
foo(int n) : bar(n)
std::vector<int>& get_vec() & return bar;
std::vector<int>&& get_vec() && return std::move(bar);
;


Then vec would be able to move the vector returned by get_vec and you save yourself an expensive copy operation.






share|improve this answer























  • @FrançoisAndrieux That's covered by my It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not. catch all. I know there are cases but I really didn't want to try and list them all.

    – NathanOliver
    3 hours ago











  • Is there a reason to prefer returning by rvalue-ref compared to returning by value here?

    – super
    3 hours ago











  • @super I take it your talking about the get_vec case? If you return by value you incur 2 move operations. Passing by rvalue reference you only have 1 move.

    – NathanOliver
    3 hours ago






  • 1





    @NathanOliver Well, you can call it on any rvalue (e.g. std::move(a).get_vec()). My point is that you're potentially returning a reference to an object that's about to be destroyed. It's the same problem as returning a reference to a local function variable.

    – Cruz Jean
    2 hours ago







  • 1





    std::vector<int> get_vec() && return std::move(bar); in this case ends up being better 999/1000. Can you come up with a better example?

    – Yakk - Adam Nevraumont
    2 hours ago



















2















T&& t = foo(); // is this a thing? And when would t get destructed?



An rvalue reference is really similar to a lvalue reference. Think about your example like it was normal references:



T& foo();

T& t = foo(); // when is t destroyed?


The answer is that t is still valid to use as long as the object is refers to lives.



The same answer still applies to you rvalue reference example.




But... does it make sense to return an rvalue reference?



Sometimes, yes. But very rarely.



consider this:



std::vector<int> v = ...;

// type is std::tuple<std::vector<int>&&>
auto parameters = std::forward_as_tuple(std::move(v));

// fwd is a rvalue reference since std::get returns one.
// fwd is valid as long as v is.
decltype(auto) fwd = std::get<0>(parameters);

// useful for calling function in generic context without copying
consume(std::get<0>(parameters));


So yes there are example. Here, another interesting one:



struct wrapper 

auto operator*() & -> Heavy&
return heavy;


auto operator*() && -> Heavy&&
return std::move(heavy);


private:
Heavy instance;
;

// by value
void use_heavy(Heavy);

// since the wrapper is a temporary, the
// Heavy contained will be a temporary too.
use_heavy(*make_wrapper());





share|improve this answer

























  • In the last example, if the wrapper instance you use this on is a temporary, operator*() returns a reference to instance, which is likewise a temporary. So after the function returns you have a reference to an object whose lifetime has ended (undefined behavior).

    – Cruz Jean
    1 hour ago











  • @CruzJean corrected

    – Guillaume Racicot
    1 hour ago


















0














I think a use case would be to explicitly give permission to "empty" some non-local variable. Perhaps something like this:



class Logger

public:
void log(const char* msg)
logs.append(msg);

std::vector<std::string>&& dumpLogs()
return std::move(logs);

private:
std::vector<std::string> logs;
;


But I admit I made this up now, I never actually used it and it also can be done like this:



std::vector<std::string> dumpLogs()
auto dumped_logs = logs;
return dumped_logs;






share|improve this answer























  • That's what the other answers have come up with as well, but in the case where this is called on a temporary object, by the time the function returns you have an (rvalue) reference to an object whose lifetime has ended (undefined behavior).

    – Cruz Jean
    1 hour ago












  • @CruzJean Well, my answer was here first and no one downvoted/complained yet so I will keep it here. I am not returning any reference to a temporary anywhere.

    – Quimby
    1 hour ago











  • return std::move(logs); where the return value is a reference type and *this is a temporary (due to being an rvalue method) makes this->logs a temporary as well. That's the reference to a temporary I mean.

    – Cruz Jean
    19 mins ago











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55958970%2fdoes-it-make-sense-for-a-function-to-return-a-rvalue-reference%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









7














For a free function it doesn't make much sense to return a rvalue reference. If it is a non-static local object then you never want to return a reference or pointer to it because it will be destroyed after the function returns. It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not.



One thing that can greatly benefit from returning an rvalue reference is a member function of a temporary object. Lets say you have



class foo

std::vector<int> bar
public:
foo(int n) : bar(n)
std::vector<int>& get_vec() return bar;
;


If you do



auto vec = foo(10).get_vec();


you have to copy because get_vec returns an lvalue. If you instead use



class foo

std::vector<int> bar
public:
foo(int n) : bar(n)
std::vector<int>& get_vec() & return bar;
std::vector<int>&& get_vec() && return std::move(bar);
;


Then vec would be able to move the vector returned by get_vec and you save yourself an expensive copy operation.






share|improve this answer























  • @FrançoisAndrieux That's covered by my It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not. catch all. I know there are cases but I really didn't want to try and list them all.

    – NathanOliver
    3 hours ago











  • Is there a reason to prefer returning by rvalue-ref compared to returning by value here?

    – super
    3 hours ago











  • @super I take it your talking about the get_vec case? If you return by value you incur 2 move operations. Passing by rvalue reference you only have 1 move.

    – NathanOliver
    3 hours ago






  • 1





    @NathanOliver Well, you can call it on any rvalue (e.g. std::move(a).get_vec()). My point is that you're potentially returning a reference to an object that's about to be destroyed. It's the same problem as returning a reference to a local function variable.

    – Cruz Jean
    2 hours ago







  • 1





    std::vector<int> get_vec() && return std::move(bar); in this case ends up being better 999/1000. Can you come up with a better example?

    – Yakk - Adam Nevraumont
    2 hours ago
















7














For a free function it doesn't make much sense to return a rvalue reference. If it is a non-static local object then you never want to return a reference or pointer to it because it will be destroyed after the function returns. It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not.



One thing that can greatly benefit from returning an rvalue reference is a member function of a temporary object. Lets say you have



class foo

std::vector<int> bar
public:
foo(int n) : bar(n)
std::vector<int>& get_vec() return bar;
;


If you do



auto vec = foo(10).get_vec();


you have to copy because get_vec returns an lvalue. If you instead use



class foo

std::vector<int> bar
public:
foo(int n) : bar(n)
std::vector<int>& get_vec() & return bar;
std::vector<int>&& get_vec() && return std::move(bar);
;


Then vec would be able to move the vector returned by get_vec and you save yourself an expensive copy operation.






share|improve this answer























  • @FrançoisAndrieux That's covered by my It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not. catch all. I know there are cases but I really didn't want to try and list them all.

    – NathanOliver
    3 hours ago











  • Is there a reason to prefer returning by rvalue-ref compared to returning by value here?

    – super
    3 hours ago











  • @super I take it your talking about the get_vec case? If you return by value you incur 2 move operations. Passing by rvalue reference you only have 1 move.

    – NathanOliver
    3 hours ago






  • 1





    @NathanOliver Well, you can call it on any rvalue (e.g. std::move(a).get_vec()). My point is that you're potentially returning a reference to an object that's about to be destroyed. It's the same problem as returning a reference to a local function variable.

    – Cruz Jean
    2 hours ago







  • 1





    std::vector<int> get_vec() && return std::move(bar); in this case ends up being better 999/1000. Can you come up with a better example?

    – Yakk - Adam Nevraumont
    2 hours ago














7












7








7







For a free function it doesn't make much sense to return a rvalue reference. If it is a non-static local object then you never want to return a reference or pointer to it because it will be destroyed after the function returns. It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not.



One thing that can greatly benefit from returning an rvalue reference is a member function of a temporary object. Lets say you have



class foo

std::vector<int> bar
public:
foo(int n) : bar(n)
std::vector<int>& get_vec() return bar;
;


If you do



auto vec = foo(10).get_vec();


you have to copy because get_vec returns an lvalue. If you instead use



class foo

std::vector<int> bar
public:
foo(int n) : bar(n)
std::vector<int>& get_vec() & return bar;
std::vector<int>&& get_vec() && return std::move(bar);
;


Then vec would be able to move the vector returned by get_vec and you save yourself an expensive copy operation.






share|improve this answer













For a free function it doesn't make much sense to return a rvalue reference. If it is a non-static local object then you never want to return a reference or pointer to it because it will be destroyed after the function returns. It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not.



One thing that can greatly benefit from returning an rvalue reference is a member function of a temporary object. Lets say you have



class foo

std::vector<int> bar
public:
foo(int n) : bar(n)
std::vector<int>& get_vec() return bar;
;


If you do



auto vec = foo(10).get_vec();


you have to copy because get_vec returns an lvalue. If you instead use



class foo

std::vector<int> bar
public:
foo(int n) : bar(n)
std::vector<int>& get_vec() & return bar;
std::vector<int>&& get_vec() && return std::move(bar);
;


Then vec would be able to move the vector returned by get_vec and you save yourself an expensive copy operation.







share|improve this answer












share|improve this answer



share|improve this answer










answered 3 hours ago









NathanOliverNathanOliver

101k16139221




101k16139221












  • @FrançoisAndrieux That's covered by my It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not. catch all. I know there are cases but I really didn't want to try and list them all.

    – NathanOliver
    3 hours ago











  • Is there a reason to prefer returning by rvalue-ref compared to returning by value here?

    – super
    3 hours ago











  • @super I take it your talking about the get_vec case? If you return by value you incur 2 move operations. Passing by rvalue reference you only have 1 move.

    – NathanOliver
    3 hours ago






  • 1





    @NathanOliver Well, you can call it on any rvalue (e.g. std::move(a).get_vec()). My point is that you're potentially returning a reference to an object that's about to be destroyed. It's the same problem as returning a reference to a local function variable.

    – Cruz Jean
    2 hours ago







  • 1





    std::vector<int> get_vec() && return std::move(bar); in this case ends up being better 999/1000. Can you come up with a better example?

    – Yakk - Adam Nevraumont
    2 hours ago


















  • @FrançoisAndrieux That's covered by my It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not. catch all. I know there are cases but I really didn't want to try and list them all.

    – NathanOliver
    3 hours ago











  • Is there a reason to prefer returning by rvalue-ref compared to returning by value here?

    – super
    3 hours ago











  • @super I take it your talking about the get_vec case? If you return by value you incur 2 move operations. Passing by rvalue reference you only have 1 move.

    – NathanOliver
    3 hours ago






  • 1





    @NathanOliver Well, you can call it on any rvalue (e.g. std::move(a).get_vec()). My point is that you're potentially returning a reference to an object that's about to be destroyed. It's the same problem as returning a reference to a local function variable.

    – Cruz Jean
    2 hours ago







  • 1





    std::vector<int> get_vec() && return std::move(bar); in this case ends up being better 999/1000. Can you come up with a better example?

    – Yakk - Adam Nevraumont
    2 hours ago

















@FrançoisAndrieux That's covered by my It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not. catch all. I know there are cases but I really didn't want to try and list them all.

– NathanOliver
3 hours ago





@FrançoisAndrieux That's covered by my It can possibly make sense to return a rvalue reference to an object that you passed to the function though. It really depends on the use case for if it makes sense or not. catch all. I know there are cases but I really didn't want to try and list them all.

– NathanOliver
3 hours ago













Is there a reason to prefer returning by rvalue-ref compared to returning by value here?

– super
3 hours ago





Is there a reason to prefer returning by rvalue-ref compared to returning by value here?

– super
3 hours ago













@super I take it your talking about the get_vec case? If you return by value you incur 2 move operations. Passing by rvalue reference you only have 1 move.

– NathanOliver
3 hours ago





@super I take it your talking about the get_vec case? If you return by value you incur 2 move operations. Passing by rvalue reference you only have 1 move.

– NathanOliver
3 hours ago




1




1





@NathanOliver Well, you can call it on any rvalue (e.g. std::move(a).get_vec()). My point is that you're potentially returning a reference to an object that's about to be destroyed. It's the same problem as returning a reference to a local function variable.

– Cruz Jean
2 hours ago






@NathanOliver Well, you can call it on any rvalue (e.g. std::move(a).get_vec()). My point is that you're potentially returning a reference to an object that's about to be destroyed. It's the same problem as returning a reference to a local function variable.

– Cruz Jean
2 hours ago





1




1





std::vector<int> get_vec() && return std::move(bar); in this case ends up being better 999/1000. Can you come up with a better example?

– Yakk - Adam Nevraumont
2 hours ago






std::vector<int> get_vec() && return std::move(bar); in this case ends up being better 999/1000. Can you come up with a better example?

– Yakk - Adam Nevraumont
2 hours ago














2















T&& t = foo(); // is this a thing? And when would t get destructed?



An rvalue reference is really similar to a lvalue reference. Think about your example like it was normal references:



T& foo();

T& t = foo(); // when is t destroyed?


The answer is that t is still valid to use as long as the object is refers to lives.



The same answer still applies to you rvalue reference example.




But... does it make sense to return an rvalue reference?



Sometimes, yes. But very rarely.



consider this:



std::vector<int> v = ...;

// type is std::tuple<std::vector<int>&&>
auto parameters = std::forward_as_tuple(std::move(v));

// fwd is a rvalue reference since std::get returns one.
// fwd is valid as long as v is.
decltype(auto) fwd = std::get<0>(parameters);

// useful for calling function in generic context without copying
consume(std::get<0>(parameters));


So yes there are example. Here, another interesting one:



struct wrapper 

auto operator*() & -> Heavy&
return heavy;


auto operator*() && -> Heavy&&
return std::move(heavy);


private:
Heavy instance;
;

// by value
void use_heavy(Heavy);

// since the wrapper is a temporary, the
// Heavy contained will be a temporary too.
use_heavy(*make_wrapper());





share|improve this answer

























  • In the last example, if the wrapper instance you use this on is a temporary, operator*() returns a reference to instance, which is likewise a temporary. So after the function returns you have a reference to an object whose lifetime has ended (undefined behavior).

    – Cruz Jean
    1 hour ago











  • @CruzJean corrected

    – Guillaume Racicot
    1 hour ago















2















T&& t = foo(); // is this a thing? And when would t get destructed?



An rvalue reference is really similar to a lvalue reference. Think about your example like it was normal references:



T& foo();

T& t = foo(); // when is t destroyed?


The answer is that t is still valid to use as long as the object is refers to lives.



The same answer still applies to you rvalue reference example.




But... does it make sense to return an rvalue reference?



Sometimes, yes. But very rarely.



consider this:



std::vector<int> v = ...;

// type is std::tuple<std::vector<int>&&>
auto parameters = std::forward_as_tuple(std::move(v));

// fwd is a rvalue reference since std::get returns one.
// fwd is valid as long as v is.
decltype(auto) fwd = std::get<0>(parameters);

// useful for calling function in generic context without copying
consume(std::get<0>(parameters));


So yes there are example. Here, another interesting one:



struct wrapper 

auto operator*() & -> Heavy&
return heavy;


auto operator*() && -> Heavy&&
return std::move(heavy);


private:
Heavy instance;
;

// by value
void use_heavy(Heavy);

// since the wrapper is a temporary, the
// Heavy contained will be a temporary too.
use_heavy(*make_wrapper());





share|improve this answer

























  • In the last example, if the wrapper instance you use this on is a temporary, operator*() returns a reference to instance, which is likewise a temporary. So after the function returns you have a reference to an object whose lifetime has ended (undefined behavior).

    – Cruz Jean
    1 hour ago











  • @CruzJean corrected

    – Guillaume Racicot
    1 hour ago













2












2








2








T&& t = foo(); // is this a thing? And when would t get destructed?



An rvalue reference is really similar to a lvalue reference. Think about your example like it was normal references:



T& foo();

T& t = foo(); // when is t destroyed?


The answer is that t is still valid to use as long as the object is refers to lives.



The same answer still applies to you rvalue reference example.




But... does it make sense to return an rvalue reference?



Sometimes, yes. But very rarely.



consider this:



std::vector<int> v = ...;

// type is std::tuple<std::vector<int>&&>
auto parameters = std::forward_as_tuple(std::move(v));

// fwd is a rvalue reference since std::get returns one.
// fwd is valid as long as v is.
decltype(auto) fwd = std::get<0>(parameters);

// useful for calling function in generic context without copying
consume(std::get<0>(parameters));


So yes there are example. Here, another interesting one:



struct wrapper 

auto operator*() & -> Heavy&
return heavy;


auto operator*() && -> Heavy&&
return std::move(heavy);


private:
Heavy instance;
;

// by value
void use_heavy(Heavy);

// since the wrapper is a temporary, the
// Heavy contained will be a temporary too.
use_heavy(*make_wrapper());





share|improve this answer
















T&& t = foo(); // is this a thing? And when would t get destructed?



An rvalue reference is really similar to a lvalue reference. Think about your example like it was normal references:



T& foo();

T& t = foo(); // when is t destroyed?


The answer is that t is still valid to use as long as the object is refers to lives.



The same answer still applies to you rvalue reference example.




But... does it make sense to return an rvalue reference?



Sometimes, yes. But very rarely.



consider this:



std::vector<int> v = ...;

// type is std::tuple<std::vector<int>&&>
auto parameters = std::forward_as_tuple(std::move(v));

// fwd is a rvalue reference since std::get returns one.
// fwd is valid as long as v is.
decltype(auto) fwd = std::get<0>(parameters);

// useful for calling function in generic context without copying
consume(std::get<0>(parameters));


So yes there are example. Here, another interesting one:



struct wrapper 

auto operator*() & -> Heavy&
return heavy;


auto operator*() && -> Heavy&&
return std::move(heavy);


private:
Heavy instance;
;

// by value
void use_heavy(Heavy);

// since the wrapper is a temporary, the
// Heavy contained will be a temporary too.
use_heavy(*make_wrapper());






share|improve this answer














share|improve this answer



share|improve this answer








edited 1 hour ago

























answered 3 hours ago









Guillaume RacicotGuillaume Racicot

16.8k53874




16.8k53874












  • In the last example, if the wrapper instance you use this on is a temporary, operator*() returns a reference to instance, which is likewise a temporary. So after the function returns you have a reference to an object whose lifetime has ended (undefined behavior).

    – Cruz Jean
    1 hour ago











  • @CruzJean corrected

    – Guillaume Racicot
    1 hour ago

















  • In the last example, if the wrapper instance you use this on is a temporary, operator*() returns a reference to instance, which is likewise a temporary. So after the function returns you have a reference to an object whose lifetime has ended (undefined behavior).

    – Cruz Jean
    1 hour ago











  • @CruzJean corrected

    – Guillaume Racicot
    1 hour ago
















In the last example, if the wrapper instance you use this on is a temporary, operator*() returns a reference to instance, which is likewise a temporary. So after the function returns you have a reference to an object whose lifetime has ended (undefined behavior).

– Cruz Jean
1 hour ago





In the last example, if the wrapper instance you use this on is a temporary, operator*() returns a reference to instance, which is likewise a temporary. So after the function returns you have a reference to an object whose lifetime has ended (undefined behavior).

– Cruz Jean
1 hour ago













@CruzJean corrected

– Guillaume Racicot
1 hour ago





@CruzJean corrected

– Guillaume Racicot
1 hour ago











0














I think a use case would be to explicitly give permission to "empty" some non-local variable. Perhaps something like this:



class Logger

public:
void log(const char* msg)
logs.append(msg);

std::vector<std::string>&& dumpLogs()
return std::move(logs);

private:
std::vector<std::string> logs;
;


But I admit I made this up now, I never actually used it and it also can be done like this:



std::vector<std::string> dumpLogs()
auto dumped_logs = logs;
return dumped_logs;






share|improve this answer























  • That's what the other answers have come up with as well, but in the case where this is called on a temporary object, by the time the function returns you have an (rvalue) reference to an object whose lifetime has ended (undefined behavior).

    – Cruz Jean
    1 hour ago












  • @CruzJean Well, my answer was here first and no one downvoted/complained yet so I will keep it here. I am not returning any reference to a temporary anywhere.

    – Quimby
    1 hour ago











  • return std::move(logs); where the return value is a reference type and *this is a temporary (due to being an rvalue method) makes this->logs a temporary as well. That's the reference to a temporary I mean.

    – Cruz Jean
    19 mins ago















0














I think a use case would be to explicitly give permission to "empty" some non-local variable. Perhaps something like this:



class Logger

public:
void log(const char* msg)
logs.append(msg);

std::vector<std::string>&& dumpLogs()
return std::move(logs);

private:
std::vector<std::string> logs;
;


But I admit I made this up now, I never actually used it and it also can be done like this:



std::vector<std::string> dumpLogs()
auto dumped_logs = logs;
return dumped_logs;






share|improve this answer























  • That's what the other answers have come up with as well, but in the case where this is called on a temporary object, by the time the function returns you have an (rvalue) reference to an object whose lifetime has ended (undefined behavior).

    – Cruz Jean
    1 hour ago












  • @CruzJean Well, my answer was here first and no one downvoted/complained yet so I will keep it here. I am not returning any reference to a temporary anywhere.

    – Quimby
    1 hour ago











  • return std::move(logs); where the return value is a reference type and *this is a temporary (due to being an rvalue method) makes this->logs a temporary as well. That's the reference to a temporary I mean.

    – Cruz Jean
    19 mins ago













0












0








0







I think a use case would be to explicitly give permission to "empty" some non-local variable. Perhaps something like this:



class Logger

public:
void log(const char* msg)
logs.append(msg);

std::vector<std::string>&& dumpLogs()
return std::move(logs);

private:
std::vector<std::string> logs;
;


But I admit I made this up now, I never actually used it and it also can be done like this:



std::vector<std::string> dumpLogs()
auto dumped_logs = logs;
return dumped_logs;






share|improve this answer













I think a use case would be to explicitly give permission to "empty" some non-local variable. Perhaps something like this:



class Logger

public:
void log(const char* msg)
logs.append(msg);

std::vector<std::string>&& dumpLogs()
return std::move(logs);

private:
std::vector<std::string> logs;
;


But I admit I made this up now, I never actually used it and it also can be done like this:



std::vector<std::string> dumpLogs()
auto dumped_logs = logs;
return dumped_logs;







share|improve this answer












share|improve this answer



share|improve this answer










answered 3 hours ago









QuimbyQuimby

1,272514




1,272514












  • That's what the other answers have come up with as well, but in the case where this is called on a temporary object, by the time the function returns you have an (rvalue) reference to an object whose lifetime has ended (undefined behavior).

    – Cruz Jean
    1 hour ago












  • @CruzJean Well, my answer was here first and no one downvoted/complained yet so I will keep it here. I am not returning any reference to a temporary anywhere.

    – Quimby
    1 hour ago











  • return std::move(logs); where the return value is a reference type and *this is a temporary (due to being an rvalue method) makes this->logs a temporary as well. That's the reference to a temporary I mean.

    – Cruz Jean
    19 mins ago

















  • That's what the other answers have come up with as well, but in the case where this is called on a temporary object, by the time the function returns you have an (rvalue) reference to an object whose lifetime has ended (undefined behavior).

    – Cruz Jean
    1 hour ago












  • @CruzJean Well, my answer was here first and no one downvoted/complained yet so I will keep it here. I am not returning any reference to a temporary anywhere.

    – Quimby
    1 hour ago











  • return std::move(logs); where the return value is a reference type and *this is a temporary (due to being an rvalue method) makes this->logs a temporary as well. That's the reference to a temporary I mean.

    – Cruz Jean
    19 mins ago
















That's what the other answers have come up with as well, but in the case where this is called on a temporary object, by the time the function returns you have an (rvalue) reference to an object whose lifetime has ended (undefined behavior).

– Cruz Jean
1 hour ago






That's what the other answers have come up with as well, but in the case where this is called on a temporary object, by the time the function returns you have an (rvalue) reference to an object whose lifetime has ended (undefined behavior).

– Cruz Jean
1 hour ago














@CruzJean Well, my answer was here first and no one downvoted/complained yet so I will keep it here. I am not returning any reference to a temporary anywhere.

– Quimby
1 hour ago





@CruzJean Well, my answer was here first and no one downvoted/complained yet so I will keep it here. I am not returning any reference to a temporary anywhere.

– Quimby
1 hour ago













return std::move(logs); where the return value is a reference type and *this is a temporary (due to being an rvalue method) makes this->logs a temporary as well. That's the reference to a temporary I mean.

– Cruz Jean
19 mins ago





return std::move(logs); where the return value is a reference type and *this is a temporary (due to being an rvalue method) makes this->logs a temporary as well. That's the reference to a temporary I mean.

– Cruz Jean
19 mins ago

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55958970%2fdoes-it-make-sense-for-a-function-to-return-a-rvalue-reference%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

François Viète Contents Biography Work and thought Bibliography See also Notes Further reading External links Navigation menup. 21Google Bookspp. 75–77Google BooksDe thou (from University of Saint Andrews)ArchivedGoogle BooksGoogle BooksGoogle BooksGoogle booksGoogle Bookscc-parthenay.frL'histoire universelle (fr)Universal History (en)ArchivedAdsabs.harvard.eduPagesperso-orange.frArchive.orgChikara Sasaki. Descartes' mathematical thought p.259Google BooksGoogle BooksGoogle Bookspp. 152 and onwardGoogle BooksGoogle BooksScribd.comGoogle Books1257-7979Google BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGallica.bnf.frGoogle BooksGoogle Books"François Viète"Francois Viète: Father of Modern Algebraic NotationThe Lawyer and the GamblerAbout TarporleySite de Jean-Paul GuichardL'algèbre nouvelle"About the Harmonicon"cb120511976(data)1188044800000 0001 0913 5903n82164680ola2013766880073431702w6vt1sb70287374827140948071409480