Does an rvalue keep its “status” when a const reference parameter binds to it?C++0x: rvalue reference versus non-const lvalueClasses, Rvalues and Rvalue ReferencesC++0x const RValue reference as function parameterPreventing non-const lvalues from resolving to rvalue reference instead of const lvalue referenceWould you ever mark a C++ RValue reference parameter as constLvalue to rvalue reference bindingPassing rvalue references vs non-const lvalue references(rvalue reference) VS (const lvalue reference) as function parameters in C++11Disable temporary binding of Eigen expression to const referencesConfusion between rvalue references and const lvalue references as parameter
Removing Doubles Destroy Topology
What city and town structures are important in a low fantasy medieval world?
On a piano, are the effects of holding notes and the sustain pedal the same for a single chord?
How can I use 400 ASA film in a Leica IIIf, which does not have options higher than 100?
What does it mean for a program to be 32 or 64 bit?
How to use Screen Sharing if I don't know the remote Mac's IP address
Ribbon Cable Cross Talk - Is there a fix after the fact?
Salesforce bug enabled "Modify All"
Why is this python script running in background consuming 100 % CPU?
Do 'destroy' effects count as damage?
Managing heat dissipation in a magic wand
How is dynamic resistance of a diode modeled for large voltage variations?
How do you cope with rejection?
What quantum phenomena violate the superposition principle in electromagnetism?
Farthing / Riding
Is there any mention of ghosts who live outside the Hogwarts castle?
Why was Harry at the Weasleys' at the beginning of Goblet of Fire but at the Dursleys' after?
Is there a realtime, uncut video of Saturn V ignition through tower clear?
What was the primary motivation for a historical figure like Xenophon to create an extensive collection of written material?
Is being an extrovert a necessary condition to be a manager?
What is this dime sized black bug with white on the segments near Loveland Colorodao?
What should I wear to go and sign an employment contract?
Does the fact that we can only measure the two-way speed of light undermine the axiom of invariance?
Barron states that 4.18×10⁸ joules equal 1 kcal, is this correct?
Does an rvalue keep its “status” when a const reference parameter binds to it?
C++0x: rvalue reference versus non-const lvalueClasses, Rvalues and Rvalue ReferencesC++0x const RValue reference as function parameterPreventing non-const lvalues from resolving to rvalue reference instead of const lvalue referenceWould you ever mark a C++ RValue reference parameter as constLvalue to rvalue reference bindingPassing rvalue references vs non-const lvalue references(rvalue reference) VS (const lvalue reference) as function parameters in C++11Disable temporary binding of Eigen expression to const referencesConfusion between rvalue references and const lvalue references as parameter
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
Let T
be an arbitrary type. Consider a function that takes a const
[lvalue] reference:
void f(const T &obj);
Suppose that this function internally makes a call to another function, which has an rvalue reference overload:
void g(T &&obj);
If we pass an rvalue to f
, will the rvalue reference overload of g
be called, or will it fail to do so since it has been "converted"/bound to a const
lvalue reference?
Similarly, if f
called a function that takes an instance of T
by value,
void h(T obj);
and T
has a move constructor, (i.e. T(T &&);
), will the move constructor be called, or will the copy constructor be called?
In conclusion, if we wanted to ensure that, when calling f
on an rvalue, the rvalue reference is passed around keeping its rvalue "status", would we necessarily have to provide an rvalue reference overload for f
?
c++ move-semantics rvalue-reference pass-by-const-reference
add a comment |
Let T
be an arbitrary type. Consider a function that takes a const
[lvalue] reference:
void f(const T &obj);
Suppose that this function internally makes a call to another function, which has an rvalue reference overload:
void g(T &&obj);
If we pass an rvalue to f
, will the rvalue reference overload of g
be called, or will it fail to do so since it has been "converted"/bound to a const
lvalue reference?
Similarly, if f
called a function that takes an instance of T
by value,
void h(T obj);
and T
has a move constructor, (i.e. T(T &&);
), will the move constructor be called, or will the copy constructor be called?
In conclusion, if we wanted to ensure that, when calling f
on an rvalue, the rvalue reference is passed around keeping its rvalue "status", would we necessarily have to provide an rvalue reference overload for f
?
c++ move-semantics rvalue-reference pass-by-const-reference
add a comment |
Let T
be an arbitrary type. Consider a function that takes a const
[lvalue] reference:
void f(const T &obj);
Suppose that this function internally makes a call to another function, which has an rvalue reference overload:
void g(T &&obj);
If we pass an rvalue to f
, will the rvalue reference overload of g
be called, or will it fail to do so since it has been "converted"/bound to a const
lvalue reference?
Similarly, if f
called a function that takes an instance of T
by value,
void h(T obj);
and T
has a move constructor, (i.e. T(T &&);
), will the move constructor be called, or will the copy constructor be called?
In conclusion, if we wanted to ensure that, when calling f
on an rvalue, the rvalue reference is passed around keeping its rvalue "status", would we necessarily have to provide an rvalue reference overload for f
?
c++ move-semantics rvalue-reference pass-by-const-reference
Let T
be an arbitrary type. Consider a function that takes a const
[lvalue] reference:
void f(const T &obj);
Suppose that this function internally makes a call to another function, which has an rvalue reference overload:
void g(T &&obj);
If we pass an rvalue to f
, will the rvalue reference overload of g
be called, or will it fail to do so since it has been "converted"/bound to a const
lvalue reference?
Similarly, if f
called a function that takes an instance of T
by value,
void h(T obj);
and T
has a move constructor, (i.e. T(T &&);
), will the move constructor be called, or will the copy constructor be called?
In conclusion, if we wanted to ensure that, when calling f
on an rvalue, the rvalue reference is passed around keeping its rvalue "status", would we necessarily have to provide an rvalue reference overload for f
?
c++ move-semantics rvalue-reference pass-by-const-reference
c++ move-semantics rvalue-reference pass-by-const-reference
edited Mar 23 at 20:05
Anakhand
asked Mar 23 at 19:51
AnakhandAnakhand
470415
470415
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
When you use the name of a reference as an expression, that expression is always an lvalue. No matter if it's a lvalue reference or an rvalue reference. It also doesn't matter if the reference was initialized with an lvalue or an rvalue.
int &&x = 1;
f(x); // Here `x` is lvalue.
So in void f(const T &obj) ...
, obj
is always an lvalue, regardless of what you pass as an argument.
Also note that value category is determined at compile time. Since f
is not a template, value category of every expression in it can't depend on arguments you pass.
Thus:
If we pass an rvalue to
f
, will the rvalue reference overload ofg
be called
No.
if
f
called a function that takes an instance ofT
by value,void h(T obj);
andT
has a move constructor, (i.e.T(T &&);
), will the move constructor be called
No.
In conclusion, if we wanted to ensure that, when calling
f
on an rvalue, the rvalue reference is passed around keeping its rvalue "status", would we necessarily have to provide an rvalue reference overload forf
?
Providing an overload is one option. Note that in this case you have to explicitly call std::move
in the rvalue overload.
Another option is using forwarding references, as Nicol Bolas suggests:
template <typename T> void f(T &&t)
g(std::forward<T>(t));
Here, std::forward
essentially acts as a 'conditional move
'. It moves t
if an rvalue was passed to it, and does nothing otherwise.
add a comment |
Value categories are applied to expressions, not objects. obj
in f
is an lvalue expression, and will therefore be treated as such. Note that obj
in g
is also an lvalue expression; if the expression is a name for an object, then it's an lvalue.
The ability you're talking about is exactly why forwarding references exist: so that the copy/move aspects of an argument expression's value category can be preserved through function calls. f
would have to become a template of the form template<typename T> void f(T&& t);
, and you would have to use std::forward
when passing it to g
.
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55317741%2fdoes-an-rvalue-keep-its-status-when-a-const-reference-parameter-binds-to-it%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
When you use the name of a reference as an expression, that expression is always an lvalue. No matter if it's a lvalue reference or an rvalue reference. It also doesn't matter if the reference was initialized with an lvalue or an rvalue.
int &&x = 1;
f(x); // Here `x` is lvalue.
So in void f(const T &obj) ...
, obj
is always an lvalue, regardless of what you pass as an argument.
Also note that value category is determined at compile time. Since f
is not a template, value category of every expression in it can't depend on arguments you pass.
Thus:
If we pass an rvalue to
f
, will the rvalue reference overload ofg
be called
No.
if
f
called a function that takes an instance ofT
by value,void h(T obj);
andT
has a move constructor, (i.e.T(T &&);
), will the move constructor be called
No.
In conclusion, if we wanted to ensure that, when calling
f
on an rvalue, the rvalue reference is passed around keeping its rvalue "status", would we necessarily have to provide an rvalue reference overload forf
?
Providing an overload is one option. Note that in this case you have to explicitly call std::move
in the rvalue overload.
Another option is using forwarding references, as Nicol Bolas suggests:
template <typename T> void f(T &&t)
g(std::forward<T>(t));
Here, std::forward
essentially acts as a 'conditional move
'. It moves t
if an rvalue was passed to it, and does nothing otherwise.
add a comment |
When you use the name of a reference as an expression, that expression is always an lvalue. No matter if it's a lvalue reference or an rvalue reference. It also doesn't matter if the reference was initialized with an lvalue or an rvalue.
int &&x = 1;
f(x); // Here `x` is lvalue.
So in void f(const T &obj) ...
, obj
is always an lvalue, regardless of what you pass as an argument.
Also note that value category is determined at compile time. Since f
is not a template, value category of every expression in it can't depend on arguments you pass.
Thus:
If we pass an rvalue to
f
, will the rvalue reference overload ofg
be called
No.
if
f
called a function that takes an instance ofT
by value,void h(T obj);
andT
has a move constructor, (i.e.T(T &&);
), will the move constructor be called
No.
In conclusion, if we wanted to ensure that, when calling
f
on an rvalue, the rvalue reference is passed around keeping its rvalue "status", would we necessarily have to provide an rvalue reference overload forf
?
Providing an overload is one option. Note that in this case you have to explicitly call std::move
in the rvalue overload.
Another option is using forwarding references, as Nicol Bolas suggests:
template <typename T> void f(T &&t)
g(std::forward<T>(t));
Here, std::forward
essentially acts as a 'conditional move
'. It moves t
if an rvalue was passed to it, and does nothing otherwise.
add a comment |
When you use the name of a reference as an expression, that expression is always an lvalue. No matter if it's a lvalue reference or an rvalue reference. It also doesn't matter if the reference was initialized with an lvalue or an rvalue.
int &&x = 1;
f(x); // Here `x` is lvalue.
So in void f(const T &obj) ...
, obj
is always an lvalue, regardless of what you pass as an argument.
Also note that value category is determined at compile time. Since f
is not a template, value category of every expression in it can't depend on arguments you pass.
Thus:
If we pass an rvalue to
f
, will the rvalue reference overload ofg
be called
No.
if
f
called a function that takes an instance ofT
by value,void h(T obj);
andT
has a move constructor, (i.e.T(T &&);
), will the move constructor be called
No.
In conclusion, if we wanted to ensure that, when calling
f
on an rvalue, the rvalue reference is passed around keeping its rvalue "status", would we necessarily have to provide an rvalue reference overload forf
?
Providing an overload is one option. Note that in this case you have to explicitly call std::move
in the rvalue overload.
Another option is using forwarding references, as Nicol Bolas suggests:
template <typename T> void f(T &&t)
g(std::forward<T>(t));
Here, std::forward
essentially acts as a 'conditional move
'. It moves t
if an rvalue was passed to it, and does nothing otherwise.
When you use the name of a reference as an expression, that expression is always an lvalue. No matter if it's a lvalue reference or an rvalue reference. It also doesn't matter if the reference was initialized with an lvalue or an rvalue.
int &&x = 1;
f(x); // Here `x` is lvalue.
So in void f(const T &obj) ...
, obj
is always an lvalue, regardless of what you pass as an argument.
Also note that value category is determined at compile time. Since f
is not a template, value category of every expression in it can't depend on arguments you pass.
Thus:
If we pass an rvalue to
f
, will the rvalue reference overload ofg
be called
No.
if
f
called a function that takes an instance ofT
by value,void h(T obj);
andT
has a move constructor, (i.e.T(T &&);
), will the move constructor be called
No.
In conclusion, if we wanted to ensure that, when calling
f
on an rvalue, the rvalue reference is passed around keeping its rvalue "status", would we necessarily have to provide an rvalue reference overload forf
?
Providing an overload is one option. Note that in this case you have to explicitly call std::move
in the rvalue overload.
Another option is using forwarding references, as Nicol Bolas suggests:
template <typename T> void f(T &&t)
g(std::forward<T>(t));
Here, std::forward
essentially acts as a 'conditional move
'. It moves t
if an rvalue was passed to it, and does nothing otherwise.
answered Mar 23 at 20:07
HolyBlackCatHolyBlackCat
17.8k33669
17.8k33669
add a comment |
add a comment |
Value categories are applied to expressions, not objects. obj
in f
is an lvalue expression, and will therefore be treated as such. Note that obj
in g
is also an lvalue expression; if the expression is a name for an object, then it's an lvalue.
The ability you're talking about is exactly why forwarding references exist: so that the copy/move aspects of an argument expression's value category can be preserved through function calls. f
would have to become a template of the form template<typename T> void f(T&& t);
, and you would have to use std::forward
when passing it to g
.
add a comment |
Value categories are applied to expressions, not objects. obj
in f
is an lvalue expression, and will therefore be treated as such. Note that obj
in g
is also an lvalue expression; if the expression is a name for an object, then it's an lvalue.
The ability you're talking about is exactly why forwarding references exist: so that the copy/move aspects of an argument expression's value category can be preserved through function calls. f
would have to become a template of the form template<typename T> void f(T&& t);
, and you would have to use std::forward
when passing it to g
.
add a comment |
Value categories are applied to expressions, not objects. obj
in f
is an lvalue expression, and will therefore be treated as such. Note that obj
in g
is also an lvalue expression; if the expression is a name for an object, then it's an lvalue.
The ability you're talking about is exactly why forwarding references exist: so that the copy/move aspects of an argument expression's value category can be preserved through function calls. f
would have to become a template of the form template<typename T> void f(T&& t);
, and you would have to use std::forward
when passing it to g
.
Value categories are applied to expressions, not objects. obj
in f
is an lvalue expression, and will therefore be treated as such. Note that obj
in g
is also an lvalue expression; if the expression is a name for an object, then it's an lvalue.
The ability you're talking about is exactly why forwarding references exist: so that the copy/move aspects of an argument expression's value category can be preserved through function calls. f
would have to become a template of the form template<typename T> void f(T&& t);
, and you would have to use std::forward
when passing it to g
.
answered Mar 23 at 20:04
Nicol BolasNicol Bolas
295k35489667
295k35489667
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55317741%2fdoes-an-rvalue-keep-its-status-when-a-const-reference-parameter-binds-to-it%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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