6 — Pass by const lvalue reference. Now an lvalue reference is a reference that binds to an lvalue. An rvalue reference can only bind to an rvalue, which is a candidate for moving. In fact, in terms of overload resolution, an rvalue prefers to be bound to an rvalue reference than to an lvalue const reference. In 9. initial value of reference to non-const must be an lvalue when calling a function. 9,096 1 33 54. reference to type 'myclass' could not bind to an rvalue of type 'myclass *'. However, the result of that conversion is an rvalue - it is a temporary object. A non-const reference may only be bound to an lvalue? I am debugging MSDN code from, (VS. There are exceptions, however. @acannon828 Okay, but then you'd be modifying the pointer that is internal to World. Another example:In the example above, SomeClass() is not bound to an identifier, so it is an rvalue and can be bound to an rvalue reference -- but not an lvalue reference. initial value of reference to non-const must be an lvalue (emphasis mine). 3 -- Lvalue references ), we discussed how an lvalue reference can only bind to a modifiable lvalue. By default, or if /Zc:referenceBinding- is specified, the compiler allows such expressions as a Microsoft extension, but a level 4 warning is issued. then the reference is bound to the initializer expression lvalue. ref]/5: — Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i. C++0x에는 rvalue reference라는 개념이 추가 됩니다. Yes, some times it is very convenient to be able to locally modify a pass-by-value argument to a function. – Vlad from Moscow. inline B& operator<< (B&& b, int) {. Note that for const auto& foo, const is qualified on the auto part, i. 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. However, A can be converted to an lvalue of type int, and const int is reference-compatible with int, so reference x of type const int can be bound to the conversion result of A(). The make_range function doesn't use that constructor. The first variant returns a reference to the actual value associated with the key test, whereas the second one returns a reference to the map element, which is a pair<const key_type, mapped_type>, i. The Rvalue refers to a value stored at an address in the memory. Thus, in case of your variable b: T = int ==> T&& becomes int&& T = int& ==> T&& becomes int. 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). That's not it. it doesn't say anything else. First of all, I will post the warning I'm getting: xlist. Actually the Standard say so: 8. The default is -qlanglvl. The this pointer is defined to be a prvalue, and your function takes an lvalue. obj & a1 = bar(); invalid initialization of non-const reference of type ‘obj&’ from an rvalue of type ‘obj’ using g++. This constness can be cast away with a const_cast<>. @KerrekSB: Binding a temporary to a const reference can cause a copy construction. By float&, he means he wants to take a reference to a float. Reload to refresh your session. Thus, in the case where P is const T&& (which is not a forwarding reference), it is transformed to const T and whether or not the argument is an lvalue doesn't affect the type deduction, since value. int&& x = 10; is a declaration and not an expression. Universal reference, or forwarding reference, only happen because of reference collapsing. But a more proper fix is to change the parameter to a const reference:However, you might need at that returns non-const reference too. This sample shows the Microsoft extension that allows a temporary of a user-defined type to be bound to a non-const lvalue reference. Apparently, the Standard agrees. i have a player class in which i have a function to return a SDL_Rect for the dimensions and the position of my player object: SDL_Rect Player::pos () { return SDL_Rect { mPosX, mPosY, PLAYER_WIDTH, PLAYER_HEIGHT }; } i get the error: "initial value of. std::string&& rref = std::string("hello"); rref has value category lvalue, and it designates a temporary object. Only expressions have values. 5) rvalues can be passed to the parameter. An lvalue (locator value) represents an object that occupies some identifiable location in memory (i. A non-const reference may only be bound to an lvalue[/quote] 1 Reply Last reply Reply Quote 0. A const reference prolongs a lifetime of a temporary object bound to it, so it is destroyed only when the reference goes out of scope. Hey Ketan Lalcheta 1. Only const lvalue references (in C++98 and C++11) or rvalue references (in C++11 only) can. So you want x to be either an. Sorted by: 6. There are better ways to solve your problems. A non-const reference must be bound to lvalue (i. 124 Non const lvalue references. , cv1 shall be const), or the reference shall be an rvalue reference. This program outputs: value = 5 value = 5. Undefined behavior can sometimes look like it's working. 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. e. Non-compliant compilers might allow a non-const or volatile lvalue reference to be bound to an rvalue. But for me a key-point with rvalue is that you can't use it afterwards, making 'move semantic' possible. Troubles understanding const in c++ (cannot bind non-const lvalue reference) 0. . The parameter of the function is an lvalue reference to non-const, and such references cannot be bound to rvalues 1. The most likely explanation is that the programmer meant to pass by const reference and just forgot the const. But an rvalue reference can't bind to an lvalue because, as we've said, an rvalue reference refers to a value whose contents it's assumed we don't need to preserve (say, the parameter for a move constructor). The rules were already more complex than "if it has a name it's an lvalue", since you have to consider the references. Consider also this: the language has no way of knowing that the lvalue reference returned by the iterator's operator * or the vector's operator[] refers to something whose lifetime is bound to that of. I understand this,. — Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i. is an xvalue, class prvalue, array prvalue or function lvalue and "cv1 T1" is reference-compatible with "cv2 T2", or. 5. It expects an lvalue reference parameter. 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. 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. Constructor by the definition does not have a return value. const int & is a const lvalue reference. & attr (optional) declarator. i have a player class in which i have a function to return a SDL_Rect for the dimensions and the position of my player object: SDL_Rect Player::pos () { return SDL_Rect { mPosX, mPosY, PLAYER_WIDTH, PLAYER_HEIGHT }; } i get the error: "initial value of. 3. Basically, VS will allocate the space somewhere and just let the reference point to it, as if it was a reference-to- const without the constness (or in C++11 an rvalue reference). aspx. 2 Copy/move constructors [class. find (key); But this returns an iterator. 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. unsigned int&). In fact, if the function returns a &, const& or &&, the object must exist elsewhere with another identity in practice. Both const and non-const reference can be binded to a lvalue. So your reference would be referring to the copy of the pointer which wouldn't be modified if you change the Player object. However, lvalue references to const forbid any change to the object and thus you may bind them to an rvalue. Share. And this is precisely what the compiler is telling you: The Lvalue refers to a modifiable object in c++ that can be either left or right side of the assignment operator. static_cast<typename remove_reference<T>::type&&> (t) The result of the function call is an rvalue (specifically, an xvalue ), so it can be bound to an rvalue reference where the function argument couldn't. The code above is also wrong, because it passes t by non-const reference. And since that the converted initializer is an xvalue not prvalue, [conv. Lvalue reference to const. ) But there is no way to show me how to solve it;You may modify a non-const object through a non-const reference. Follow. Cannot bind non-const lvalue reference to an rvalue. The reference is. You need to pass in an rvalue, and for that you need to use std::move: I can see why this is counter-intuitive!The site you got the code from is the explanation why this warning appears, it's the example code for reproducing it. An lvalue reference (commonly just called a reference since prior to C++11 there was only one type of reference) acts as an alias for an existing lvalue (such as a variable). , cv1 shall be const), or the reference shall be an rvalue reference. For some convenience, the const refs were "extended" to be able to point to a temporary. 21. It's just that non-const lvalue references can't bind to rvalues, so the can never be used that way. 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. Remember that an rvalue binds to a const lvalue reference, hence if you did: template <typename T> void foo (const T& bar) { /*. cpp(10): warning C4239: nonstandard extension used : 'argument' : conversion from '<type1>' to '<type2>' 1> A non-const reference may only be bound to an lvalue" only on warning level /W4 or above. Without rvalue expression, we could do only one of the copy assignment/constructor and move assignment/constructor. (Binding to a const reference is allowed. If an rvalue could bind to a non-const lvalue reference, then potentially many modifications could be done that would eventually be discarded (since an rvalue is temporary), this being useless. Or, passing it by const reference will also work, since a const lvalue reference can be. thanks in advance, George. That is special syntax for a so-called forwarding reference. 0f, c); The other similar calls need to be fixed too. )An variable name (which is normally an lvalue) can be moved in a return statement if it names an implicitly movable entity: An implicitly movable entity is a variable of automatic storage duration that is either a non-volatile object or an rvalue reference to a non-volatile object type. The type of such a reference must be a const qualified lvalue reference or a rvalue references. ReferencesAnother option is to make push() be a template with a forwarding reference of type U, using a concept/SFINAE to make sure that U is compatible with the class's main T type. Is it for optimization purposes? Take this example:By overloading a function to take a const lvalue reference or an rvalue reference, you can write code that distinguishes between non-modifiable objects (lvalues) and modifiable temporary values. 2 Answers. int f( int ); int f( int && ); int f( int const & ); int q = f( 3 ); Removing f( int ) causes both Clang and GCC to prefer the rvalue reference over the lvalue reference. 1. e. 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. constexpr T& value() &; constexpr const T & value() const &; constexpr T&& value() &&; constexpr const T&& value() const &&; What is the point of returning a const rvalue reference? The only reason I can think of is to enable the compiler to help catch undefined behavior in (really really weird) cases like the followingA non-const reference may only be bound to an lvalue[/quote] Reply Quote 0. You can implement a method and have one "version" for a const object, and one for a non-const object. C++: Variable that is passed by const referance changes value. " I really need some further explanations to solving this: #include "graph1. After some investigation and help from the community, here is the answer:. A reference variable declaration is any simple declaration whose declarator has the form. The following example shows the function g, which is overloaded to take an lvalue reference and an rvalue. 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. */ } And called the function with: foo (createVector ()); It'd work fine. ref]/5:. The rules were already more complex than "if it has a name it's an lvalue", since you have to consider the references. They could also bind to rvalues but only when the. So in your case, you need to rewrite your. 2/5 in N4140): A temporary bound to a reference parameter in a function call (5. 3. But doesn't work when instantiated over non class types (as I expected)This change is required by the C++ standard which specifies that a non-const. a copy would be needed). It cannot be done with lvalue references to non-const since they cannot be bound to rvalues. What "r-value reference for this` does is allow you to add another alternative: void RValueFunc () &&; This allows you to have a function that can only be called if the user calls it through a proper r-value. Regarding the second question. However,. C++ prohibits passing a temporary object as a non-const reference parameter. (I) An rvalue had been bound to an lvalue reference to a non-const or volatile type. 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. In the case of int inner(). Now it makes actually sense to take its address, as it is an lvalue for all intents and purposes. 2. An expression that designates a bit-field (e. GetCollider (). rvalues can be residing on read-only memory spaces where changing them might not be allowable and hence the compiler prohibits them. 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. “An old special-case permits an rvalue to be bound to an lvalue reference to non-const type when that reference is the. The parameter list for a move constructor, however, consists of an rvalue reference, like B&& x. Hot Network QuestionsNon-const references cannot bind to rvalues, it's as simple as that. However, you might need at that returns non-const reference too. There are exceptions, however. Pointers have a difference, pointer can be changed. the first version essentially returns second of said pair directly. 5. The compiler automatically generates a temporary that the reference is bound to. You are returning a copy of A from test so *c triggers the construction of a copy of c. int& func() { int x = 0; return x; } compiles, but it returns a reference to a stack variable that no longer exists. e. const char*&). How to fix depends on what the return type of cleverConfig. name. Community Bot. Some older compilers couldn't support the latter in proper way. 2: the reference shall be an lvalue reference to a non-volatile const type (i. Maybe because you're not doing anything the call is optimized away. Value categories are applied to expressions, not objects. This can only bind to a const reference, and then the objec's lifetime will be extended to the lifetime of the const reference it is bound to (hence "binding"). – Kerrek SB. But that doesn't make sense. operator[] . Remember Me? Forum; FAQ; Calendar; Forum Actions. Since the temporary B that's returned by source () is not. All (lvalue, rvalue, const, non-const) -> const lvalue. 7 = a; The compiler / interpreter will work out the right hand side (which may or may not be const), and then put it into the left hand side. Fun fact: /W3 is set. including the case where an lvalue is provided, it cannot modify its input (at least not the one bound to the x parameter) - if it did, it would violate the semantics. Visual C++ is non-compliant with the standard in allowing binding of temporaries to non-const lvalue references. 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. This could also be achieved with a non-const lvalue reference, but then they would have to. GetCollider(). Actor & actor = get_actor_ref_from_ped (PLAYER::PLAYER_PED_ID ()); ^^^^^^^ reference. And an rvalue reference is a reference that binds to an rvalue. Thus you know that you are allowed to manipulate it without damaging other data. The term “identity” is used by the C++ standard, but is not well-defined. If C++ allowed you to take literals by non-const reference, then it would either: Have to allow literals to change their meaning dynamically, allowing you to make 1 become 2. A operator*(const A& a) const { A res; res. g. 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. struct S {}; f<S {}> (); // ok. Writing it gives you the chance to do it wrong (which you already did by. It is unusual to use references to iterators. Good article to understand both lvalue and rvalue references is C++ Rvalue References Explained. e. I have fixed these issues and completely understand how/why it gives a warning. Rvalues (including xvalues) can be bound to const lvalue references so that you can pass a temporary to a function with such a parameter:With pointers, you can mostly correctly use const and non const versions, whatever is more appropriate (i. Rvalue references should be unconditionally cast to rvalues when forwarding them to other functions: void sink (ConcreteType&& ct) // can only be called on rvalues { collection. In the second case, fun() returns a non-const lvalue reference, which can bind to another non-const reference, of course. And this is precisely what the compiler is telling you:. And until now we've only touched what already used to happen in C++98. For lvalue references, T is deduced to be an lvalue reference, and for rvalue references, T is deduced to be a non-reference. It's the first const that I'm unsure of. thus, this is legal: string&& s = foo (); // extends lifetime as before s += "bar"; baz (std::move (s)); // move the temporary into the baz function. 80). a nonconst reference could only binded to lvalue. and if you pass it to a function that takes a reference to a non-const - it means that function can change the value. 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. How to fix depends on what the return type of cleverConfig. Both of g and h are legal and the reference binds directly. Allowing both rvalues and lvalues to be bound to an lvalue reference makes that impossible. 3. [ Example: double& rd2 = 2. In the following codes, I have two versions of class A instantiated, one is bound to int and the other to int&. If t returns a local variable, then you get a dangling reference, since that variable is gone after the call. The temporary unsigned int could be bound to lvalue-reference to const (i. Only modifiable lvalue expressions may be used as arguments to increment/decrement, and as left-hand arguments of assignment and compound. Thus, the standard allows all types. of the Microsoft compiler. Follow edited Nov 15, 2016 at. (non const) lvalue reference and rvalue that also means that you can convert the rvalue into an lvalue and therefore. Return by value. , temporary) double but a temporary cannot be bound to a non-const reference. A function parameter such as T&& t is known as a forwarding reference. Add a comment. Every non-static data member of E must be a direct member of E or the same base class of E, and must be well-formed in the context of the structured binding when named as e. temporary] ( §12. Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i. init. A glvalue may be implicitly converted to a prvalue with lvalue-to-rvalue,. 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. e. an expression with rvalue reference type, you will have to use std::move or equivalent. Such one reference is called an lvalue reference to a constant true (sometimes called a reference to konst or a const. 255 (i. Temporary objects cannot be bound to non-const references; they can only. They can bind to const lvalue-references because then a promise has been made. Actually for simple types you should prefer to pass by value instead, and let the optimizer worry about providing the best implementation. Note also that if you simply use CList<DATA>, the second template argument ARG_TYPE is correctly deduced to be const DATA& by default, as per CList template declaration (TYPE = DATA, ARG_TYPE = const DATA&): template<class TYPE, class ARG_TYPE = const TYPE&> class CList : public CObjectT& data; There's your problem. Same thing can be done with lvalue references to const: const int& x = 10. But result of such conversion is an rvalue, so your reference to non-const cannot be bound to it. In the case of storing a value, the type can be non-const and the function could modify that object, so the approach is more flexible. The const subscript operator returns a const-reference, so the compiler will prevent callers from inadvertently mutating/changing the Fred. 4. 11. And plus more, in this case if I called. 2nd that, nullptr is the best way to declare the optional parameter. What is the reason behind disallowing binding an rvalue to an lvalue reference. Similarly, if an lvalue is passed to factory, it is forwarded to T's constructor as an lvalue. – Joseph Mansfield. Rule: lvalue, rvalue, const or non-const objects can bind to const lvalue parameters. This function receives as a second parameter a const lvalue reference, this is an lvalue and then it calls to copy assignment. push_back (std::move (obj)); } If caller passes an lvalue, then there is a copy (into the parameter) and a move (into the vector). -hg. The option -qlanglvl=compatrvaluebinding instructs the compiler to allow a non-const or volatile lvalue reference to bind to an. New rvalue reference rules were set by the C++ specification. not an rvalue reference, everything under the sun can be bound by a forwarding reference – Piotr Skotnicki. match. 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. In this case, returning a non-const lvalue reference compiles because x is an lvalue (just one whose lifetime is about to end). C++ initial value of reference to non-const must be an lvalue and I'm sure I have done everything right. Generally speaking, when a function takes a parameter by non-const. a. 3. warning C4239: nonstandard extension used: 'default argument': conversion from 'std::shared_ptr' to 'std::shared_ptr &'. A temporary is a prvalue whilst a reference is a lvalue. Non-const reference may only be bound to an lvalue. g. A temporary can only bind to const lvalue references, or rvalue references. Of course the left value of an assignment has to be non-const. e. A C++ reference is similar to a pointer, but acts more like an alias. In the above program, because value parameter y is a copy of x, when we increment y, this only affects y. Your declaration of a is a non-const lvalue reference,. Fibonacci Series in C++. If the initializer expression. Lvalue and rvalue expressions. However, I am. Universal references is a technique. Here you are taking a reference to a uint8Vect_t. h(418) : warning C4239: nonstandard extension used : 'argument' : conversion from 'XUTIL::xList<T>::iterator' to. So if this is in the type Object:So we have a reference being initialized by an xvalue of type const foo. For example, a const lvalue reference should bind to both lvalue and rvalue arguments, and a non-const lvalue reference should bind to a non-const lvalue, but refuse to bind to rvalues and const lvalues. It can take rvalues because it is marked const and rvalues are allowed to bind to const lvalue references. find (key);A pointer to non-const is convertible to pointer to const however. The core of your question is: can rvalues be bound to non-const lvalue references?. 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. For reference, the sentence that totally misled me is in [over. Modified 6 years,. This operator is trying to return an lvalue reference to a temporary created upon returning from the function: mat2& operator /= ( const GLfloat s. is an xvalue, class prvalue, array prvalue or function lvalue and "cv1 T1" is reference-compatible with "cv2 T2", or. If an rvalue is passed to factory, then an rvalue will be passed to T's constructor with the help of the forward function. ; T is not reference-related to U. qual] or even [conv. C++ does not give that feature to non-const references: 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 to e or a base class subobject of e unless T is an inaccessible or ambiguous base class of U. So the parameter list for a copy constructor consists of an const lvalue reference, like const B& x . const reference to non-const object. Therefore, if we make a reference parameter const, then it will be able to bind to any type of argument:I suppose I'd think of it along the lines of, in C++: If I have a mutable lvalue reference a and const lvalue reference b to the same object, I can always mutate b by mutating a. What you were trying to do isn't much different from writing a function that takes a mutable reference to int (e. ref/6] ). Const reference can be bounded to. 806 3 3 gold badges 12 12 silver badges 20 20 bronze badges. 5. ("variable" means object or reference). So naming kInt is not deemed an odr-use as long as it. 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. It can appear only on the right-hand side of the assignment operator. Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i. 1. e, the condition. The lifetime extension is not transitive through a. if binding temporary to local non-const lvalue reference is allowed, you may write the code like this :. 1 Answer. However, in VS2010 I seem to be able to do so:. What you're trying to perform is making a reference to a temporary value which is not allowed. 1 1 1. (5. In this context, binding an rvalue to the non-const reference behaves the same as if you were binding it to a const reference. Rule 3, "Note: if the initializer for a reference of type const T& is. However, int can be implicitly converted to double and this is happening. So an expression returning a non-const reference is still considered an lvalue. const unsigned int&), (and its lifetime is extended to the lifetime of the reference,) but can't be bound to lvalue-reference to non-const (i. But instead removing either reference overload results in ambiguity with f( int ). has a class type. Share. init. e. This is old extension to Visual Studio, the only reference I could find on the Microsoft site was this bug report: Temporary Objects Can be Bound to Non-Const References, which has the following example code: struct A {}; A f1 (); void f2 (A&); int main () { f2 (f1 ()); // This line SHALL trigger an error, but it can be compiled. png", 560, 120); int x2 = 560 + 54; int x1 = 560; int y1 = 120; int y2 = 291 + 120; const int * xSolv2 = &x2. Share. 4 — Lvalue references to const. Since the temporary B that's returned by source () is not. template <auto N> void f () { auto & n = N; } This works when f is instantiated over class types. A non-const lvalue reference can only bind to non-const lvalues. an lvalue, this constructor cannot be used, so the compiler is forced to use. This won't work. 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. Don't pass int&, it can't be bound to a constant or temporary because those can't be modified - use const int& instead. e. There's no difference between a bound rvalue reference and a bound lvalue reference. C++ : Non-const reference may only be bound to an lvalueTo Access My Live Chat Page, On Google, Search for "hows tech developer connect"As promised, I have a. You can call a non-const member function only on a non-const object. 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). U is a class type. That works well with normal variables but uint8Vect_t(dataBlock. If t returns a local variable, then you get a dangling reference, since that variable is gone after the call. void checkMe (shared_ptr<string>& param = shared_ptr<string> ()); This MSDN article says it is a /W4 warning. 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. e. e. 2. That's an exception to the general rule that it is impossible for lvalues to be bound to rvalue. The option -qlanglvl=compatrvaluebinding instructs the compiler to allow a. Now, when printValue(x) is called, lvalue reference parameter y is bound to argument x. 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. 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 recommend checking how standard library deals with this. 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 forward should decay into an lvalue reference anyways, right? c++; perfect-forwarding; Share. My understanding is that this is largely to avoid breaking several enormous legacy codebases that rely on this "extension. Accept all cookies Necessary cookies only Customize settings. Both const and non-const reference can be binded to a lvalue. Hence, C++ does not permit a non-const reference to a const variable. There are exceptions, however. std::vector<bool> is special from all other std::vector specializations. rvalues cannot bind to non-const references. 3.