Is there a way to detect if the current member function is operating on an lvalue or rvalue?What are rvalues,...
Was it really necessary for the Lunar Module to have 2 stages?
How can Republicans who favour free markets, consistently express anger when they don't like the outcome of that choice?
Can someone publish a story that happened to you?
Please, smoke with good manners
Stateful vs non-stateful app
Smart diagram in Mathematica
Do I have an "anti-research" personality?
How do I deal with a coworker that keeps changing the look of a report I'm building, without documenting the changes in a design template?
Counterexample: a pair of linearly ordered sets that are isomorphic to subsets of the other, but not isomorphic between them
Was there a Viking Exchange as well as a Columbian one?
Corner spot where three faces meet
Where can i find the changelog of a snap package
How does a swashbuckler fight with two weapons and safely dart away?
Has any spacecraft ever had the ability to directly communicate with civilian air traffic control?
Were there two appearances of Stan Lee?
How to figure out whether the data is sample data or population data apart from the client's information?
Is creating your own "experiment" considered cheating during a physics exam?
Alternatives to Overleaf
Normal subgroup of even order whose nontrivial elements form a single conjugacy class is abelian
Do I have to worry about players making “bad” choices on level up?
Killing undead fish underwater
Why does processed meat contain preservatives, while canned fish needs not?
Why is the origin of “threshold” uncertain?
How to stop co-workers from teasing me because I know Russian?
Is there a way to detect if the current member function is operating on an lvalue or rvalue?
What are rvalues, lvalues, xvalues, glvalues, and prvalues?Implicitly treating returned lvalue as rvaluePass lvalue to rvalueWould you ever mark a C++ RValue reference parameter as constData members as lvalue-reference or rvalue-copiesHow do I prevent code repeat between rvalue and lvalue member functions?std::mem_fn with ref_qualified member functionsReturning a member from an rvalue objectseparate handlers lvalue and rvalue [] operatorsLvalue to rvalue conversion with integer pointer
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
Qualifiers are a great way to overload functions based on context of the object. Such qualifiers are const
and volatile
. However, writing code for them is annoying as they are usually duplication of code as the cv qualifiers are at least propagated by this
. As such, we can make the entire function (sans cv qualifiers) exactly the same using propagation tricks and with the help of auto
or decltype(auto)
.
E.g.:
struct X {
int m_i = 0;
auto& i() & { return m_i ; } // returns int &
auto& i() volatile & { return m_i ; } // returns int volatile &
auto& i() const & { return m_i ; } // returns int const &
auto& i() const volatile & { return m_i ; } // returns int const volatile &
};
Although annoying, at least we can see that this is going to work in all contexts with the same code and thus minimizes error.
However, with the new lvalue/rvalue qualifiers that can be used to specify member functions, this
doesn't propagate whether the function was called on an object that is an lvalue or rvalue. This results in having to make slight variations of the function, if say I wanted to do this:
struct X {
int m_i = 0;
auto&& i() & { return m_i ; } // returns int &
auto&& i() volatile & { return m_i ; } // returns int volatile &
auto&& i() const & { return m_i ; } // returns int const &
auto&& i() const volatile & { return m_i ; } // returns int const volatile &
auto&& i() && { return std::move(m_i); } // returns int &&
auto&& i() volatile && { return std::move(m_i); } // returns int volatile &&
auto&& i() const && { return std::move(m_i); } // returns int const &&
auto&& i() const volatile && { return std::move(m_i); } // returns int const volatile &&
};
It would be nice to be able to make them all the same.
Something like this:
struct X {
int m_i = 0;
decltype(auto) i() & { return std::forward<...some_magic...>(m_i); } // returns int &
decltype(auto) i() volatile & { return std::forward<...some_magic...>(m_i); } // returns int volatile &
decltype(auto) i() const & { return std::forward<...some_magic...>(m_i); } // returns int const &
decltype(auto) i() const volatile & { return std::forward<...some_magic...>(m_i); } // returns int const volatile &
decltype(auto) i() && { return std::forward<...some_magic...>(m_i); } // returns int &&
decltype(auto) i() volatile && { return std::forward<...some_magic...>(m_i); } // returns int volatile &&
decltype(auto) i() const && { return std::forward<...some_magic...>(m_i); } // returns int const &&
decltype(auto) i() const volatile && { return std::forward<...some_magic...>(m_i); } // returns int const volatile &&
};
Is there any means to interrogate if the current member function is operating on an lvalue or rvalue?
c++ c++17
|
show 1 more comment
Qualifiers are a great way to overload functions based on context of the object. Such qualifiers are const
and volatile
. However, writing code for them is annoying as they are usually duplication of code as the cv qualifiers are at least propagated by this
. As such, we can make the entire function (sans cv qualifiers) exactly the same using propagation tricks and with the help of auto
or decltype(auto)
.
E.g.:
struct X {
int m_i = 0;
auto& i() & { return m_i ; } // returns int &
auto& i() volatile & { return m_i ; } // returns int volatile &
auto& i() const & { return m_i ; } // returns int const &
auto& i() const volatile & { return m_i ; } // returns int const volatile &
};
Although annoying, at least we can see that this is going to work in all contexts with the same code and thus minimizes error.
However, with the new lvalue/rvalue qualifiers that can be used to specify member functions, this
doesn't propagate whether the function was called on an object that is an lvalue or rvalue. This results in having to make slight variations of the function, if say I wanted to do this:
struct X {
int m_i = 0;
auto&& i() & { return m_i ; } // returns int &
auto&& i() volatile & { return m_i ; } // returns int volatile &
auto&& i() const & { return m_i ; } // returns int const &
auto&& i() const volatile & { return m_i ; } // returns int const volatile &
auto&& i() && { return std::move(m_i); } // returns int &&
auto&& i() volatile && { return std::move(m_i); } // returns int volatile &&
auto&& i() const && { return std::move(m_i); } // returns int const &&
auto&& i() const volatile && { return std::move(m_i); } // returns int const volatile &&
};
It would be nice to be able to make them all the same.
Something like this:
struct X {
int m_i = 0;
decltype(auto) i() & { return std::forward<...some_magic...>(m_i); } // returns int &
decltype(auto) i() volatile & { return std::forward<...some_magic...>(m_i); } // returns int volatile &
decltype(auto) i() const & { return std::forward<...some_magic...>(m_i); } // returns int const &
decltype(auto) i() const volatile & { return std::forward<...some_magic...>(m_i); } // returns int const volatile &
decltype(auto) i() && { return std::forward<...some_magic...>(m_i); } // returns int &&
decltype(auto) i() volatile && { return std::forward<...some_magic...>(m_i); } // returns int volatile &&
decltype(auto) i() const && { return std::forward<...some_magic...>(m_i); } // returns int const &&
decltype(auto) i() const volatile && { return std::forward<...some_magic...>(m_i); } // returns int const volatile &&
};
Is there any means to interrogate if the current member function is operating on an lvalue or rvalue?
c++ c++17
some magic
Note that programming languages don't rely on magic.
– πάντα ῥεῖ
2 hours ago
1
@πάνταῥεῖ, are you serious or you poking fun at my fun? :D
– Adrian
2 hours ago
1
Puulease, don't format code like that.
– Neil Butterworth
2 hours ago
@Adrian I am absolutely serious. Check this please.
– πάντα ῥεῖ
2 hours ago
@πάνταῥεῖ, it was meant as an offhand joke. Should I change it to...some science...
? :D :D
– Adrian
2 hours ago
|
show 1 more comment
Qualifiers are a great way to overload functions based on context of the object. Such qualifiers are const
and volatile
. However, writing code for them is annoying as they are usually duplication of code as the cv qualifiers are at least propagated by this
. As such, we can make the entire function (sans cv qualifiers) exactly the same using propagation tricks and with the help of auto
or decltype(auto)
.
E.g.:
struct X {
int m_i = 0;
auto& i() & { return m_i ; } // returns int &
auto& i() volatile & { return m_i ; } // returns int volatile &
auto& i() const & { return m_i ; } // returns int const &
auto& i() const volatile & { return m_i ; } // returns int const volatile &
};
Although annoying, at least we can see that this is going to work in all contexts with the same code and thus minimizes error.
However, with the new lvalue/rvalue qualifiers that can be used to specify member functions, this
doesn't propagate whether the function was called on an object that is an lvalue or rvalue. This results in having to make slight variations of the function, if say I wanted to do this:
struct X {
int m_i = 0;
auto&& i() & { return m_i ; } // returns int &
auto&& i() volatile & { return m_i ; } // returns int volatile &
auto&& i() const & { return m_i ; } // returns int const &
auto&& i() const volatile & { return m_i ; } // returns int const volatile &
auto&& i() && { return std::move(m_i); } // returns int &&
auto&& i() volatile && { return std::move(m_i); } // returns int volatile &&
auto&& i() const && { return std::move(m_i); } // returns int const &&
auto&& i() const volatile && { return std::move(m_i); } // returns int const volatile &&
};
It would be nice to be able to make them all the same.
Something like this:
struct X {
int m_i = 0;
decltype(auto) i() & { return std::forward<...some_magic...>(m_i); } // returns int &
decltype(auto) i() volatile & { return std::forward<...some_magic...>(m_i); } // returns int volatile &
decltype(auto) i() const & { return std::forward<...some_magic...>(m_i); } // returns int const &
decltype(auto) i() const volatile & { return std::forward<...some_magic...>(m_i); } // returns int const volatile &
decltype(auto) i() && { return std::forward<...some_magic...>(m_i); } // returns int &&
decltype(auto) i() volatile && { return std::forward<...some_magic...>(m_i); } // returns int volatile &&
decltype(auto) i() const && { return std::forward<...some_magic...>(m_i); } // returns int const &&
decltype(auto) i() const volatile && { return std::forward<...some_magic...>(m_i); } // returns int const volatile &&
};
Is there any means to interrogate if the current member function is operating on an lvalue or rvalue?
c++ c++17
Qualifiers are a great way to overload functions based on context of the object. Such qualifiers are const
and volatile
. However, writing code for them is annoying as they are usually duplication of code as the cv qualifiers are at least propagated by this
. As such, we can make the entire function (sans cv qualifiers) exactly the same using propagation tricks and with the help of auto
or decltype(auto)
.
E.g.:
struct X {
int m_i = 0;
auto& i() & { return m_i ; } // returns int &
auto& i() volatile & { return m_i ; } // returns int volatile &
auto& i() const & { return m_i ; } // returns int const &
auto& i() const volatile & { return m_i ; } // returns int const volatile &
};
Although annoying, at least we can see that this is going to work in all contexts with the same code and thus minimizes error.
However, with the new lvalue/rvalue qualifiers that can be used to specify member functions, this
doesn't propagate whether the function was called on an object that is an lvalue or rvalue. This results in having to make slight variations of the function, if say I wanted to do this:
struct X {
int m_i = 0;
auto&& i() & { return m_i ; } // returns int &
auto&& i() volatile & { return m_i ; } // returns int volatile &
auto&& i() const & { return m_i ; } // returns int const &
auto&& i() const volatile & { return m_i ; } // returns int const volatile &
auto&& i() && { return std::move(m_i); } // returns int &&
auto&& i() volatile && { return std::move(m_i); } // returns int volatile &&
auto&& i() const && { return std::move(m_i); } // returns int const &&
auto&& i() const volatile && { return std::move(m_i); } // returns int const volatile &&
};
It would be nice to be able to make them all the same.
Something like this:
struct X {
int m_i = 0;
decltype(auto) i() & { return std::forward<...some_magic...>(m_i); } // returns int &
decltype(auto) i() volatile & { return std::forward<...some_magic...>(m_i); } // returns int volatile &
decltype(auto) i() const & { return std::forward<...some_magic...>(m_i); } // returns int const &
decltype(auto) i() const volatile & { return std::forward<...some_magic...>(m_i); } // returns int const volatile &
decltype(auto) i() && { return std::forward<...some_magic...>(m_i); } // returns int &&
decltype(auto) i() volatile && { return std::forward<...some_magic...>(m_i); } // returns int volatile &&
decltype(auto) i() const && { return std::forward<...some_magic...>(m_i); } // returns int const &&
decltype(auto) i() const volatile && { return std::forward<...some_magic...>(m_i); } // returns int const volatile &&
};
Is there any means to interrogate if the current member function is operating on an lvalue or rvalue?
c++ c++17
c++ c++17
asked 2 hours ago
AdrianAdrian
4,20522162
4,20522162
some magic
Note that programming languages don't rely on magic.
– πάντα ῥεῖ
2 hours ago
1
@πάνταῥεῖ, are you serious or you poking fun at my fun? :D
– Adrian
2 hours ago
1
Puulease, don't format code like that.
– Neil Butterworth
2 hours ago
@Adrian I am absolutely serious. Check this please.
– πάντα ῥεῖ
2 hours ago
@πάνταῥεῖ, it was meant as an offhand joke. Should I change it to...some science...
? :D :D
– Adrian
2 hours ago
|
show 1 more comment
some magic
Note that programming languages don't rely on magic.
– πάντα ῥεῖ
2 hours ago
1
@πάνταῥεῖ, are you serious or you poking fun at my fun? :D
– Adrian
2 hours ago
1
Puulease, don't format code like that.
– Neil Butterworth
2 hours ago
@Adrian I am absolutely serious. Check this please.
– πάντα ῥεῖ
2 hours ago
@πάνταῥεῖ, it was meant as an offhand joke. Should I change it to...some science...
? :D :D
– Adrian
2 hours ago
some magic
Note that programming languages don't rely on magic.– πάντα ῥεῖ
2 hours ago
some magic
Note that programming languages don't rely on magic.– πάντα ῥεῖ
2 hours ago
1
1
@πάνταῥεῖ, are you serious or you poking fun at my fun? :D
– Adrian
2 hours ago
@πάνταῥεῖ, are you serious or you poking fun at my fun? :D
– Adrian
2 hours ago
1
1
Puulease, don't format code like that.
– Neil Butterworth
2 hours ago
Puulease, don't format code like that.
– Neil Butterworth
2 hours ago
@Adrian I am absolutely serious. Check this please.
– πάντα ῥεῖ
2 hours ago
@Adrian I am absolutely serious. Check this please.
– πάντα ῥεῖ
2 hours ago
@πάνταῥεῖ, it was meant as an offhand joke. Should I change it to
...some science...
? :D :D– Adrian
2 hours ago
@πάνταῥεῖ, it was meant as an offhand joke. Should I change it to
...some science...
? :D :D– Adrian
2 hours ago
|
show 1 more comment
1 Answer
1
active
oldest
votes
No, there isn't.
The only access you have to yourself within the confines of a member function body is: this
. And this
is always a X [cv]* const
, and *this
is always an lvalue - an X [cv]&
. It can tell you what the cv-qualifiers of the member function are, but it cannot tell you what the ref-qualifiers of the function are.
You would have to indirect all of your member functions to a non-member function, passing yourself approrpiately as an lvalue or rvalue:
decltype(auto) i() & { return free_i(*this); }
decltype(auto) i() && { return free_i(std::move(*this)); }
template <typename Self>
friend decltype(auto) free_i(Self&& self) { ... }
P0847 solves this as well, but that won't be in C++20 either. Maybe C++23:
template <typename Self>
decltype(auto) i(this Self&& self) { ... }
Here, you can straightforwardly pull off what kind of reference self
is.
Yeah, I'm already using the free function template method, though using a template static member function instead. I will be very happy when P0847 comes into realization as this is quite annoying.
– Adrian
2 hours ago
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%2f55892101%2fis-there-a-way-to-detect-if-the-current-member-function-is-operating-on-an-lvalu%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
No, there isn't.
The only access you have to yourself within the confines of a member function body is: this
. And this
is always a X [cv]* const
, and *this
is always an lvalue - an X [cv]&
. It can tell you what the cv-qualifiers of the member function are, but it cannot tell you what the ref-qualifiers of the function are.
You would have to indirect all of your member functions to a non-member function, passing yourself approrpiately as an lvalue or rvalue:
decltype(auto) i() & { return free_i(*this); }
decltype(auto) i() && { return free_i(std::move(*this)); }
template <typename Self>
friend decltype(auto) free_i(Self&& self) { ... }
P0847 solves this as well, but that won't be in C++20 either. Maybe C++23:
template <typename Self>
decltype(auto) i(this Self&& self) { ... }
Here, you can straightforwardly pull off what kind of reference self
is.
Yeah, I'm already using the free function template method, though using a template static member function instead. I will be very happy when P0847 comes into realization as this is quite annoying.
– Adrian
2 hours ago
add a comment |
No, there isn't.
The only access you have to yourself within the confines of a member function body is: this
. And this
is always a X [cv]* const
, and *this
is always an lvalue - an X [cv]&
. It can tell you what the cv-qualifiers of the member function are, but it cannot tell you what the ref-qualifiers of the function are.
You would have to indirect all of your member functions to a non-member function, passing yourself approrpiately as an lvalue or rvalue:
decltype(auto) i() & { return free_i(*this); }
decltype(auto) i() && { return free_i(std::move(*this)); }
template <typename Self>
friend decltype(auto) free_i(Self&& self) { ... }
P0847 solves this as well, but that won't be in C++20 either. Maybe C++23:
template <typename Self>
decltype(auto) i(this Self&& self) { ... }
Here, you can straightforwardly pull off what kind of reference self
is.
Yeah, I'm already using the free function template method, though using a template static member function instead. I will be very happy when P0847 comes into realization as this is quite annoying.
– Adrian
2 hours ago
add a comment |
No, there isn't.
The only access you have to yourself within the confines of a member function body is: this
. And this
is always a X [cv]* const
, and *this
is always an lvalue - an X [cv]&
. It can tell you what the cv-qualifiers of the member function are, but it cannot tell you what the ref-qualifiers of the function are.
You would have to indirect all of your member functions to a non-member function, passing yourself approrpiately as an lvalue or rvalue:
decltype(auto) i() & { return free_i(*this); }
decltype(auto) i() && { return free_i(std::move(*this)); }
template <typename Self>
friend decltype(auto) free_i(Self&& self) { ... }
P0847 solves this as well, but that won't be in C++20 either. Maybe C++23:
template <typename Self>
decltype(auto) i(this Self&& self) { ... }
Here, you can straightforwardly pull off what kind of reference self
is.
No, there isn't.
The only access you have to yourself within the confines of a member function body is: this
. And this
is always a X [cv]* const
, and *this
is always an lvalue - an X [cv]&
. It can tell you what the cv-qualifiers of the member function are, but it cannot tell you what the ref-qualifiers of the function are.
You would have to indirect all of your member functions to a non-member function, passing yourself approrpiately as an lvalue or rvalue:
decltype(auto) i() & { return free_i(*this); }
decltype(auto) i() && { return free_i(std::move(*this)); }
template <typename Self>
friend decltype(auto) free_i(Self&& self) { ... }
P0847 solves this as well, but that won't be in C++20 either. Maybe C++23:
template <typename Self>
decltype(auto) i(this Self&& self) { ... }
Here, you can straightforwardly pull off what kind of reference self
is.
answered 2 hours ago
BarryBarry
189k21337618
189k21337618
Yeah, I'm already using the free function template method, though using a template static member function instead. I will be very happy when P0847 comes into realization as this is quite annoying.
– Adrian
2 hours ago
add a comment |
Yeah, I'm already using the free function template method, though using a template static member function instead. I will be very happy when P0847 comes into realization as this is quite annoying.
– Adrian
2 hours ago
Yeah, I'm already using the free function template method, though using a template static member function instead. I will be very happy when P0847 comes into realization as this is quite annoying.
– Adrian
2 hours ago
Yeah, I'm already using the free function template method, though using a template static member function instead. I will be very happy when P0847 comes into realization as this is quite annoying.
– Adrian
2 hours ago
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%2f55892101%2fis-there-a-way-to-detect-if-the-current-member-function-is-operating-on-an-lvalu%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
some magic
Note that programming languages don't rely on magic.– πάντα ῥεῖ
2 hours ago
1
@πάνταῥεῖ, are you serious or you poking fun at my fun? :D
– Adrian
2 hours ago
1
Puulease, don't format code like that.
– Neil Butterworth
2 hours ago
@Adrian I am absolutely serious. Check this please.
– πάντα ῥεῖ
2 hours ago
@πάνταῥεῖ, it was meant as an offhand joke. Should I change it to
...some science...
? :D :D– Adrian
2 hours ago