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;
}







7















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?










share|improve this question























  • 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


















7















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?










share|improve this question























  • 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














7












7








7


1






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?










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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



















  • 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












1 Answer
1






active

oldest

votes


















5














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.






share|improve this answer
























  • 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














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%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









5














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.






share|improve this answer
























  • 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


















5














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.






share|improve this answer
























  • 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
















5












5








5







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.






share|improve this answer













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.







share|improve this answer












share|improve this answer



share|improve this answer










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





















  • 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






















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%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





















































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

“%fieldName is a required field.”, in Magento2 REST API Call for GET Method Type The Next...

How to change City field to a dropdown in Checkout step Magento 2Magento 2 : How to change UI field(s)...

夢乃愛華...