You can implement a method and have one "version" for a const object, and one for a non-const object. e. What you probably want is: BYTE *pImage = NULL; x. " I really need some further explanations to solving this: #include "graph1. You signed out in another tab or window. The second version is only allowed non-const rvalues because you can't implicitly strip const from the referencee and rvalue references don't allow lvalues to bind. A reference variable declaration is any simple declaration whose declarator has the form. If it is not immediately obvious, we can try to check: Therefore, you can opt to change your getPtr ()'s return to a non-const lvalue reference. Since rvalues cannot be bound to non-const lvalue references, this condition is not satisfied here. Assignment to references, on the other hand, is implicit, so if a is of type int& you simply need to write a=b to make a a reference to b. r-value:-. int a = 7. 6 — Pass by const lvalue reference. For example, the argument might be a reference to a node of a linked list, and within the function you may want to traverse the list, so you will want to be doing node = * (node. If t returns by rvalue reference, you obtain a reference to whatever was returned. 4. e. It's not against the rules in C++ to use a non-const reference but I think it lends to massive confusion and potential bugs. Calling operator + second time won't be possible because a temporary object can not be passed as reference to a non-const-qualified object. A const lvalue reference can be initialized from a bit-field. Within the body of a non-static member function of X, any id-expression e (e. However sometimes it is desired to ensure that you can only pass lvalues to a function (this is the case for std::ref for one). In such cases: [1] First, implicit type conversion to T is applied if necessary. e. it is explained that an lvalue is when you can take its address. Apparently, the Standard agrees. A reference is only allowed to bind to a lvalue. E may not have an anonymous union member. rvalue Reference Cannot Bind to a Named lvalue. it is only accessing the string objects in the array that a points to, so there is no need to pass a by reference, passing it by value will work just fine: void spell(int n, string* a) Live Demo. It's not against the rules in C++ to use a non-const reference but I think it lends to massive confusion and potential bugs. The core of your question is: can rvalues be bound to non-const lvalue references?. Non-const reference may only be bound to an lvalue. However, now you've got a temporary A, and that cannot bind to a, which is a non-const lvalue reference. init. non-const lvalue reference to type 'int' cannot bind to a. Share. For example, when passing things by value, or else with things like A a; B b = a;. 0; // error: not an lvalue and reference not const int i = 2; double& rd3 = i; // error: type mismatch and reference not const —end example]A non-const reference may only be bound to an lvalue[/quote] 1 Reply Last reply Reply Quote 0. In the above code, getStr(); on line 12 is an rvalue since it returns a temporary object as well as the right-hand side of the expression on line 13. , cv1 shall be const), or the reference shall be an rvalue. Both of g and h are legal and the reference binds directly. Non-const reference may only be bound to an lvalue. It can take rvalues because it is marked const and rvalues are allowed to bind to const lvalue references. push_back (std::move (obj)); } If caller passes an lvalue, then there is a copy (into the parameter) and a move (into the vector). So if this is in the type Object:So we have a reference being initialized by an xvalue of type const foo. Hey Ketan Lalcheta 1. Mar 22, 2013 at 18:39. 124 Non const lvalue references. an identifier) that resolves to a non-type non-static member of X or of a base class of X, is transformed to a member access. Writing it gives you the chance to do it wrong (which you already did by. e. Confusion between rvalue references and const lvalue references as parameter. Moreover, taking the value string by mutable lvalue reference in the call operator of your MapInserter is not a good idea: you don't want the argument to be modified, so you should either take it by const& or - my advice - take it by value and then move it into the returned pair, like so:A conversion is something like "An lvalue/xvalue/prvalue expression of type T may be converted to an lvalue/xvalue/prvalue expression of type U. 3/5, [dcl. Reference is always constant, you can't change reference. "A reference to type 'cv1 T1' is initialized" refers to the variable that is being initialized, not to the expression in its initializer. Your conclusion happens to be correct, but it doesn't follow from your premise. So the parameter list for a copy constructor consists of an const lvalue reference, like const B& x . Only local const references prolong the lifespan. Modified 6 years,. Overload between rvalue reference and const lvalue reference in template. Can someone given an example of a "non-const lvalue reference"? I need to pass an object to a routine where the object's state will be modified, after the routine has completed I expect to use the object with the modified state. I'm not sure why the compiler is trying to bind the non-const lvalue reference to an rvalue. Improve this question. Otherwise. However, since Visual C++ allows this as an extension, how does it work? From what I've gathered, the standard does not allow this since you're getting a reference to a temporary variable, which can cause issues. 2), an xvalue if T is an rvalue reference to object type, and a prvalue otherwise. According to the reference collapsing rules, "rvalue reference to rvalue reference collapses to rvalue reference, all other combinations form lvalue reference". int&& x = 10; is a declaration and not an expression. 71. C++/SDL "initial value of reference to a non-const must be an lvalue" 0 non-const lvalue reference to type 'const int *' cannot bind to a value of unrelated type 'int *It is very rarely a good idea to pass a pointer by const &: at best it takes the same overhead, at worst it causes extremely complex pointer reseating logic to surprise readers of your code. There are exceptions, however. If t were really an out-parameter, it would be passed by pointer: std::string *t. Non-const reference may only be bound to an lvalue. Accept all cookies Necessary cookies only Customize settings. and another 7 more if your interested, all saying about the same thing. It doesn't really matter. This may sound like a silly question, but I was confused about this following behaviour:. Non-const reference may only be bound to an lvalue. Now consider the second call site, with the temporary value: MyClass myObject{std::string{"hello"}}; myObject. The reference returned from get_value is bound to x which is an l-value, and that's allowed. You know, just like any other use of const. We can't bind rvalue reference to an lvalue also. Secondly, your variable is const (as it is constexpr), and a non-const reference cannot be bound to a const object. The code below is not legal (problem with the foo_t initializer list) because: "A reference that is not to 'const' cannot be bound to a non-lvalue" How can I best achieve an. @YueZhou Function lvalues may be bound to rvalue references. temporary] ( §12. Early on, when we teach modern C++, we teach that every non-small 1 data should be passed, by default, as constant reference: 1. – The outcome is that the code compiles and works when using MSVC, but doesnt on GCC and Clang, with respective errors: GCC: cannot bind non-const lvalue reference of type 'FuncPtr<bool ()>&' to an rvalue of type 'FuncPtr<bool ()>' Clang: no matching constructor for initialization of 'A'. You can either modify the return type of the function from Value* to const Value& , or opt for return *cleverconfig[name]; . A non-const reference may only be bound to an lvalue[/quote] 1 Reply Last reply Reply Quote 0. Alex November 11, 2023 In the previous lesson ( 12. It's not against the rules in C++ to use a non-const reference but I think it lends to massive confusion and potential bugs. non-const reference of type from an rvalue. e. An lvalue (pronounced “ell-value”, short for “left value” or “locator value”, and sometimes written as “l-value”) is an expression that evaluates to an identifiable object or function (or bit-field). Non-compliant compilers might allow a non-const or volatile lvalue reference to be bound to an rvalue. Some similar case give me the reason: The C++ standard does not allow the binding of an anonymous temporary to a reference, although some compilers allow it as an extension. Solution 3: When you call with , the address-of operator creates a temporary value , and you can't normally have references to temporary values because they are, well, temporary. The simplest fix is to simply store the temporary object somewhere, first: Collider c=player. 2/5 in N4140): A temporary bound to a reference parameter in a function call (5. By using the const keyword when declaring an lvalue reference, we tell an lvalue reference to treat the object it is referential when const. 4. This rule covers not only cases such as. 0 Invalid initialization of non-const reference from a. We can't bind non-const lvalue reference to an rvalue, but it can be bound to the const one. 3. If I were to call it with an rvalue, C++ would shout at me. In your code, int & is a non-const lvalue reference. –Most of the time you don't want a non-const lvalue reference to refer to some temporary object. A operator*(const A& a) // Return a value, not a reference. initial value of reference to non-const must be an lvalue. const A& x = 1; //compile x = 2; //error! A&& xxx = 1; //compile A& xx = 1; //does not compile. Now it makes actually sense to take its address, as it is an lvalue for all intents and purposes. A usual lvalue reference (to a non-const value) won’t do. Just as if you had done: typedef long long type; const type& x = type(l); // temporary! Contrarily an rvalue, as you know, cannot be bound to a non-const reference. The most likely explanation is that the programmer meant to pass by const reference and just forgot the const. 6. The call would bind to f(int&&). What std::string::c_str returns is an rvalue, which can't be bound to an lvalue-reference to non-const (i. By default, or if /Zc:referenceBinding- is specified, the compiler allows such expressions as a Microsoft extension, but a level 4 warning is issued. In the second case, fun() returns a non-const lvalue reference, which can bind to another non-const reference, of course. 1. For some convenience, the const refs were "extended" to be able to point to a temporary. This is fulfilled by two types being similar, which basically means if they are the same type with the same number of pointers but possibly different cv-qualifiers (e. I have looked elsewhere on this site and read similar postings about this error: "initial value of reference to a non-const must be lvalue. : if at least one operand is of class type and has a conversion-to-reference operator, the result may be an lvalue designating the object designated by the return value of that operator; and if the designated object is actually a temporary, a dangling reference may result. That works well with normal variables but uint8Vect_t(dataBlock. A non-const reference may only be bound to an lvalue? I am debugging MSDN code from, (VS. What this means is that it's technically possible for the function to modify the pointer itself in a way that gets propagated to the caller. Just remove the Fraction(Fraction& f) constructor. A temporary object may not be bound to a non constant reference. Ok, so, I already know that returning a local variable as reference will cause undefined behavior when we try to use it and that we can create a non-const reference to only form a lvalue variable. the pointer but not the pointee. e. thanks in advance, George. GetImage (iTileId, pulImageSize, a_pImage ); With the method defined as:This change is required by the C++ standard which specifies that a non-const. at returns a proxy (of type std::vector<bool>::reference) that allows you to write the element. I get tired of writing a pair of iterators and make a View class. (I'll comment on all the answers. That's not it. Although the standard formulates it in other words (C++17 standard draft [dcl. Create_moneys () is a function that takes a mutable reference to a pointer. You can normally hide the expression template type behind private members. Changing it to void display (const double& arg) works because everything works the same as explained above. 1. A variable is an lvalue, so you are allowed to bind a non const reference to it. Values are fine: auto refInstance = m_map. – Kerrek SB. inline B& operator<< (B&& b, int) {. a is an expression. Now an lvalue reference is a reference that binds to an lvalue. (Binding to a const reference is allowed. Potentially related articles: Overload resolution between object, rvalue reference, const reference; std::begin and R-values; For a STL container C, std::begin(C) and similar access functions including std::data(C) (since C++17) are supposed to have the same behavior of C::begin() and the other corresponding C's methods. A function lvalue; If an rvalue reference or a nonvolatile const lvalue reference r to type T is to be initialized by the expression e, and T is reference-compatible with U, reference r can be initialized by expression e and bound directly to e or a base class subobject of e unless T is an inaccessible or ambiguous base class of U. end()) is a temporary object and cannot be bound to lvalue reference. Non-const reference may only be bound to an lvalue. You are returning a reference to a local variable. On the contrary, rvalues can be bound to const lvalue references. 1/4 of N3337:. Unfortunately, they may compile with one common compiler, due to language. C++/SDL "initial value of reference to a non-const must be an lvalue". You can pass lvalues to functions taking rvalues as arguments (tested using a C++ editor). RVO may explain this particular quark, but you cannot return a reference to something that doesn't exist. It reflects the old, not the new. e. If you are unsure what an lvalue expression is, see this answer. decltype(fun()) b=1; Then, your code initializes a const reference with a prvalue of a different (non-reference-related) type. If /Zc:referenceBinding is specified, the compiler follows section 8. If you are trying to modify the variable 'pImage' inside the method 'GetImage ()' you should either be passing a pointer or a reference to it (not doing both). You are returning a copy of A from test so *c triggers the construction of a copy of c. What is the reason behind disallowing binding an rvalue to an lvalue reference. The code above is also wrong, because it passes t by non-const reference. Find more info here. Sometimes even for the original developer, but definitely for future maintainers. and if you pass it to a function that takes a reference to a non-const - it means that function can change the value. Not that std::forward has a return type that looks like T&&. Improve this answer. If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A ” is used in place of A for type deduction. First of all, an argument to such a reference must have static storage duration and linkage, which your variable cannot have both as it is defined in block-scope. Actually the precise reason it doesn't work is not because temporaries cannot be bound to non-const lvalue references, but rather that the initializer of a non-const lvalue reference is subject to certain requirements that char const[N] cannot meet in this case, [dcl. Case 3: binding to data members. Specifically, a const rvalue will prefer to bind to the const rvalue reference rather than the const lvalue reference. 9,096 1 33 54. This example is very similar to the previous one, except the temporary object is non-const this time. " followed by a specification of how the result of the conversion is determined. , you may only want to hold on to a const Bar*, in which case you then can also only pass a const Bar*) Using a const Bar& as parameter type is bound to result in a runtime crash sooner rather than later because:The C++ Standard (2003) indicates that an rvalue can only be bound to a const non-volatile lvalue reference. A reference (of any kind) is just an alias for the referenced object. , cv1 shall be const), or the reference shall be an rvalue reference. So an expression returning a non-const reference is still considered an lvalue. You obviously can't point to a temporary. This approach does not work for two reasons: First, because we modify the source object, we have to pass it as a non-const reference. void my_function (const MyType & arg); This avoids the copy of these parameters in situations where they don’t need to be copied. C++ prohibits passing a temporary object as a non-const reference parameter. . And an rvalue reference is a reference that binds to an rvalue. at(0) = false; The reaons is that x. Named variables are lvalues. So if the function binds to a rvalue reference, what is seen at the end by the compiler for a certain type T is: std::is_rvalue_reference<T>::value. The only difference (that I see) is that x2 knows it only has 3 rows, whereas x1 has a dynamic number of rows. Rule 3, "Note: if the initializer for a reference of type const T& is. One const and the other non. The concepts of lvalue expressions and rvalue expressions are sometimes brain-twisting, but rvalue reference together with lvalue reference gives us more flexible options for programming. That is special syntax for a so-called forwarding reference. When you pass a pointer by a non- const reference, you are telling the compiler that you are going to modify that. The behaviour of this is to copy-initialize a temporary of the same type as the reference. This operator is trying to return an lvalue reference to a temporary created upon returning from the function: A temporary or an rvalue cannot be changed with a reference to non-const. You cannot do that with a non-member function that accepts an lvalue reference. Apr 14 at 22:55. initial value of reference to non-const must be an lvalue, Passing an object type by. 3/5. C. 2. That is to say, usage of a reference is syntactically identical to usage of the referent. e. I do not quite understand why there is a warning A non-const reference may only be bound to an lvalue? A const reference can be bound to: R-value L-value A non-const reference can be bound to: L-value This means that you can do this: int const &x = 5; But you _can't_ do this: int &x = 5;, thus preventing you from trying to modify a literal, or. The ability you're talking about is exactly why forwarding references exist: so that the copy/move aspects. 4. Apr 13, 2017 at 13:00. In this case, returning a non-const lvalue reference compiles because x is an lvalue (just one whose lifetime is about to end). 0. Data members: Never const. 4. It got me quite curious. Regarding the second question. init. The const subscript operator returns a const-reference, so the compiler will prevent callers from inadvertently mutating/changing the Fred. Example 5 @relent95 Yes, whether the id-expression refers to a variable of reference or non-reference type doesn't matter because of what you quoted. " Rule 2, "A non-const reference shall not be bount to a bit-field". The binding rules for rvalue references now work differently in one. If t returns by lvalue reference, the code does not compile because a rvalue reference cannot bind to it. Consulting the cppreference documentation for <type_traits>, it appears that there is not such a tool in the standard library. , temporary) double but a temporary cannot be bound to a non-const reference. ) But there is no way to show me how to solve it;You may modify a non-const object through a non-const reference. */ } And called the function with: foo (createVector ()); It'd work fine. e. By float&, he means he wants to take a reference to a float. Unlike a reference to non-const (which can only bind to modifiable lvalues), a reference to const can bind to modifiable lvalues, non-modifiable lvalues, and rvalues. 0; // error: not an lvalue and reference not const int i = 2; double& rd3 = i; // error: type mismatch and reference not const —end example] Although not directly related to this case there is another very important difference between const and non-const references. 3. You can't bind a temporary to a non-const lvalue-reference because it doesn't make much sense to modify, say, a literal like 42. Testing tools for web developers. I do not quite understand why there is a warning A non-const reference may only be bound to an lvalue and 'B::B (A)' called instead of 'B::B (B &)'? think. Sounds like you actually want getPlayer to return a reference too and then to. // zcreferencebinding. It can appear only on the right-hand side of the assignment operator. The conformant behavior does not allow binding a non-const reference to an rvalue. Improve this question. ctor] A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are. My question is, why a non-const reference can not binded to a rvalue? I think the reason is rvalue is not addressable? And we can not change the rvalue through its reference?Warning: "A non-const reference may only be bound to an lvalue" I've encountered a very weird warning that, although compiles fine on windows, fails to. The method forward has const in its parameter, so the int& version should have the parameter const int& t. non-const lvalue reference to type cannot bind. warning C4239: nonstandard extension used : 'initializing' : conversion from 'foo' to 'foo &' A non-const reference may only be bound to an lvalue (note that this remains illegal in C++11) Last edited on Dec 20, 2011 at 2:37am UTC Otherwise, if the reference is lvalue reference to a non-volatile const-qualified type or rvalue reference (since C++11): If target is a non-bit-field rvalue or a function lvalue, and its type is either T or derived from T , equally or less cv-qualified, then the reference is bound to the value of the initializer expression or to its base. I can't understand why I have to specify the dynamic type to make it work. If t returns a local variable, then you get a dangling reference, since that variable is gone after the call. 5. Const reference can be bounded to. Then the type of foo would be Foo* const &, which is a reference to const (pointer to non-const Foo), but not const Foo* &, which is a reference to non-const (pointer to const Foo). Saturday, December 15, 2007 4:49 AM. It seems perfectly reasonable for the standard to have been that a temporary is created, and dropped at the end of the function's execution (as you currently have to manually do). The rules were already more complex than "if it has a name it's an lvalue", since you have to consider the references. g. if binding temporary to local non-const lvalue reference is allowed, you may write the code like this :. a copy would be needed). Thank you. It's just that type of that lvalue is "rvalue reference to Key ". . If caller passes an rvalue, then there are two moves (one into parameter and another into vector). On the other hand lvalue references to const forbids any change to the object they reference and thus you may bind them to a rvalue. That's an exception to the general rule that it is impossible for lvalues to be bound to rvalue. You can change the parameter type to const char* in or const char* const & in if in won't be modified in UTF8toWide() , or use a named variable instead. CheckCollision (0. Binding a reference is always inexpensive,. So in your case, you need to rewrite your. There is a special rule in the language that allows binding a const lvalue reference to the rvalue (whether const or not) by extending the lifetime of the rvalue to match the lifetime of the. Take a look at the swap function signature: swap ( shared_ptr& r ). (Binding to a const reference is allowed. I recommend checking how standard library deals with this. 3 of the C++11 standard: It doesn't allow expressions that bind a user-defined type temporary to a non-const lvalue reference. U is a class type. All rvalues are non-const. m. has an address). Community Bot. In the previous lesson ( 12. However, an rvalue can be bound to a. An rvalue may be used to initialize a const lvalue [ rvalue] reference, in which case the lifetime of the object identified by the rvalue is extended until the scope of the reference ends. An expression that designates a bit-field (e. See universal. begin(), dataBlock. I have to think for a while-_-!. It's just that non-const lvalue references can't bind to rvalues, so the can never be used that way. is an xvalue, class prvalue, array prvalue or function lvalue and "cv1 T1" is reference-compatible with "cv2 T2", or. This constness can be cast away with a const_cast<>. Because a reference to a non-const value can only bind to a modifiable lvalue (essentially a non. ) But there is no way to show me how to solve it;You may modify a non-const object through a non-const reference. a nonconst reference could only binded to lvalue. 1. Assume a variable name as a label attached to its location in memory. , cv1 shall be const), or the reference shall be an rvalue reference. Hot Network Questions Identifying traffic signals for colour blind peopleBut thinking further about it, I think it might be OK :-) Imagine there were three consts (not just two) in const Array &operator=( const Array & ) const; The last const is unacceptable, as it can't even modify itself. The compiler automatically generates a temporary that the reference is bound to. Jun 17, 2016 at 3:16. 25th May 2022, 8:44 AM. Thus, in case of your variable b: T = int ==> T&& becomes int&& T = int& ==> T&& becomes int. A C++ reference is similar to a pointer, but acts more like an alias. The second version is only allowed non- const rvalues because you can't implicitly strip const from the referencee and rvalue references don't allow lvalues to bind to them. Note that the table indicates that an rvalue cannot bind to a non-const lvalue reference. The lifetime extension is not transitive through a. it doesn't say anything else. is an xvalue, class prvalue, array prvalue or function lvalue and "cv1 T1" is reference-compatible with "cv2 T2", or. The first option can take lvalues because it's an lvalue reference. If t returns a local variable, then you get a dangling reference, since that variable is gone after the call. (The small difference is that the the lambda-expression is converted to a temporary std::function - but that still can't be bound to a non-const reference). So if the function binds to a rvalue reference, what is seen at the end by the compiler for a certain type T is: std::is_rvalue_reference<T>::value. This extends the lifetime of the temporary: base * const &rp = (base*)p; Or bind the reference to an lvalue: base * b = p; base * &rp = b; Share. However, this is deceptive, because it may or may not be an rvalue reference depending on the type of T. Solution 1: Your problem lies here: The variable is an lvalue reference, that means it's a reference that cannot bind to temporary variables. initial value of reference to non-const must be an lvalue (emphasis mine). print(); This one matches the third constructor, and moves the value inside of the storage. This means the following. Const reference can be bounded to. And this is precisely what the compiler is telling you:. and forwards messages that it receives to that object. The language forbids that sort of binding for various reasons. The reference is. ningaman151 November 23, 2019, 7:39pm 8. Otherwise, if the reference is lvalue reference to a non-volatile const-qualified type or rvalue reference (since C++11): If target is a non-bit-field rvalue or a function lvalue, and its type is either T or derived from T , equally or less cv-qualified, then the reference is bound to the value of the initializer expression or to its base. — Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i. The whole idea of forwarding is to accept any value category and preserve it for future calls. Jan 8, 2015 at 8:51. const char*&). Constant lvalue references can be bound to all types of values, including non-constant lvalues, constant lvalues. Const reference can be bounded to. not an rvalue reference, everything under the sun can be bound by a forwarding reference – Piotr Skotnicki. However, C++ makes one exception to this rule and allows const lvalue references to also bind to rvalues. Am getting cannot bind non-const lvalue reference of type ‘Type&’ to an rvalue of type 'Type'The function returns a pointer, which you are trying to bind to a reference. The only way to safely bind an rvalue to an lvalue is either by. No, "returning a reference" does not magically extend any lifetime. e. Non-const lvalue reference to type '_wrap_iter' cannot bind to a value of unrelated type '_wrap_iter' c++;. –The pointer returned by the function cannot be bound to a reference. Unless an object is created in the read-only section of a program, it is open for modifiction without adverse consequences. A function lvalue; If an rvalue reference or a non-volatile const lvalue reference r to type T is to be initialized by the expression e, and T is reference-compatible with U, reference r can be initialized by expression e and bound directly toe or a base class subobject of e unless T is an inaccessible or ambiguous base class of U. – You may not bind a temporary object with a non-constant lvalue reference. I recently filed a bug against MSVC which relates to this, where the non-standard behavior caused standard-compliant code to fail to compile and/or compile with a deviant behavior. Thank you. So naming kInt is not deemed an odr-use as long as it. Unless an object is created in the read-only section of a program, it is open for modifiction without adverse consequences. ;, x is an lvalue denoting a float whose value is the result of converting a to double and back. i. You can call a non-const member function only on a non-const object. Because a reference to a non-const value can only bind to a modifiable lvalue (essentially a non-const variable), this means that pass by reference only works with arguments that are modifiable lvalues. the expression c is an lvalue, even though the reference may have been bound to a temporary object at the time of calling. Such one reference is called an lvalue reference to a constant true (sometimes called a reference to konst or a const. Am getting cannot bind non-const lvalue reference of type ‘Type&’ to an rvalue of type 'Type' The function returns a pointer, which you are trying to bind to a reference. g. It looks like well formed code with defined behavior to me. "The temporary to which the reference is bound or the temporary that is the complete object of a sub-object to which the reference is bound persists for the lifetime of the reference. To handle other value categories, one may use std::forward_as_tuple:. Share. Return by value. std::tie always expects lvalues for arguments, since its intended purpose is to be used in assignment. 2 Answers. Example 51) Is actually not so arbitrary. You can call a non-const member function on a temporary because this does not involve binding of a reference. struct Foo{}; { const auto & r = Foo{}; // Foo object not destroyed at semicolon. //. I could even (though this is a bit unusual) safely const_cast away the constness of b, since I also hold a non-const reference to the same object. May 4, 2013 at 16:38. -1.