It could even do so with std::move only. For details, see Set C++ compiler and build properties in Visual Studio. I would like to move an object into a std::vector using std::vector::push_back(). lval), array-to-pointer (conv. A reference (“lvalue reference” since C++11) is a type of C++ variable that can act as an alias to another value. It's also echoed in 5. Then I use rvalue reference of class B's this pointer to pass it to A's constructor. Your issue is. (For example std::function<void()> can be constructed. 1 Answer. ; In all other cases, the cast result is a (prvalue) rvalue. This is not an rvalue reference. References. When you use "Hello, World" in a context in which it is implicitly converted to a const char* pointing to its initial element, the resulting pointer is an rvalue (because it is a temporary object resulting from an implicit. An lvalue is a value bound to a definitive region of memory whereas an rvalue is an expression value whose existence is temporary and who does not necessarily refer to a definitive region of memory. key here is Key&& key - this is an lvalue! It has a name, and you can take its address. By tracing slt_pair. It cannot convert from an rvalue to an lvalue reference, even a const one. You must explicitly use std::move (or a cast) to convert an lvalue into an rvalue reference, and an rvalue reference will never bind to an lvalue on its own. You will often find explanations that deal with the left and right side of an assignment. Yes, if you pass an lvalue const char* to a function accepting a const char*, that'll work. The terms "lvalue/rvalue reference" and "lvalue/rvalue" are related but not interchangeable or one a shortened form of the other. lvalueはアドレスを取得できるがrvalueはアドレスを取得できない。 これは一見見分ける強力な手段に思える。しかし考えて欲しい。コードを書くときにいちいちアドレス演算子を書いてコンパイルしてみるなんて悠長なことをするだろうか、いいやしない。2 Answers. It's been part of the language since the beginning. The expressions f (), f (). I couldn't find an example of l2r applicable to class types myself; in all the seemingly applicable examples there's usually a function involved that takes lvalue-ref (like copy-ctor), for which l2r seems to be suppressed (see. Even though the object in question is a temporary object, its lifetime has been extended. The pre-C++ origin of the terms "lvalue" and "rvalue" might be related to "left" and "right" side of assignment, but that meaning is only applicable in a small subset of the C++ language. 0. And so on. and write_Lvalue will only accept an lvalue. Let's look at (T1&&)t2 first. When an lvalue-to-rvalue conversion is applied to an expression e, and either. For example, this code will not compile. 1) modifiable lvalues. Second (and you probably missed that), const char* is converted to a rvalue std::string via the const char* non-explicit constructor of std::string (# 5 in the link). If you write arg+1 inside the function, the lvalue expression arg of type int would. Such an expression is always an lvalue, even if x is an rvalue and even if y is an rvalue reference. Lvalues and xvalues can be of incomplete types, but (prvalue) rvalues must be of complete types or void types. 12. A so called 'rvalue-reference' can bind to a temporary , but anything with a name is an lvalue, so you need to forward<> () it if you need it's rvalueness back. 45. That is special syntax for a so-called forwarding reference. int & a = b * 5 is invalid. That's to protect people from changing the values of temporaries that are destroyed before their new value can be used . As we've seen earlier, a and b are both lvalues. 4. @MikeMB the standard rarely prevents compilers from inserting for (int i = 0; i < 1 billion; ++i) at arbitrary points. Understanding Lvalues and Rvalues. You can use an lvalue almost anywhere where an rvalue is required and an implicit lvalue to rvalue conversion will occur automatically. 1 Answer. An object is a region of storage that can be examined and stored into. In the case of object constructing is true but in the case of object assigning is false. 0. lvalues and rvalues lvalue –writable memory location; has an address int a; rvalue –data at readable memory location or readonly value that doesn’t have an address Transient (temporary) variable (register, means that we cannot change it’s value in C/C++, only to fetch) constant (including addresses) 5 = a; //An rvalue is a type of expression, not a type of object. Otherwise, the reference you get behaves more. 14159, are rvalues. The example is interesting because it seems that only lvalues are combined. This is. There are operators that yield lvalues: for example, if E is an expression of pointer type, then *E is an lvalue expression referring to the object to which E points. That's right according also to the C++ Standard (talking about the lvalue-to-rvalue conversion): 4. Using it only makes sense inside of a template, where you choose whether to move or not depending on a template argument. 3. オブジェクトという言葉が聞き慣れないなら. For non-class types you cannot assign to rvalues. So MSVC++ is giving incorrect result (in case of C++ code). Example: int a. When programming in C++03, we can't pass an unnamed temporary T () to a function void foo (T&);. The Parent class stores a pointer, but due to rvalue to lvalue conversion, the Parent ends up storing a reference to a pointer. Therefore it makes sense that they are mutable. the original code was int&& rref = n; which was ill-formed, as n is an lvalue and therefore cannot bind to an rvalue reference. x is not assignable, because it's an rvalue in 03, a prvalue in 11 and an xvalue in 14, but using a member function always allows you to convert rvalues to lvalues (because *this is always an lvalue). Used to move the resources from a source object i. C++ pass parameter by rvalue reference if possible, otherwise copy the lvalue reference. 2 1). It's actually a cast. Whenever an lvalue is used in a position in which an rvalue is expected, the compiler performs an lvalue-to-rvalue conversion and then. The terms are somewhat language-specific; they were first introduced in CPL. The value of x is 1. 1 Answer. An lvalue may get converted to an rvalue: that's something perfectly legit and it happens quite often. rvalue (until C++11) / prvalue (since C++11)Since you are giving your rvalue reference a name in the parameter list, it indeed becomes an lvalue. Share. have lvalues passed by reference). The result of the expression (T) cast-expression is of type T. We're talking about the temporary object created by Contrived(), it doesn't make sense to say "this object is an rvalue". An obvious example of an lvalue expression is an identifier with suitable type and storage class. const foo&& can only bind to an rvalue, but const foo& can bind to both lvalues and rvalues. goo<int> is an lvalue of function type, but expressions of function type are. One that returns an int used when a rvalue is needed. cast (this is applicable from C++11 and later). The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type and an xvalue if T is an rvalue reference to object type; otherwise the result is a prvalue. It matches arguments of any value category, making t an lvalue reference if the supplied argument was an lvalue or an rvalue reference if the supplied argument was an rvalue. Move semantics relies on a new feature of C++11, called rvalue references, which you'll want to understand to really appreciate what's going on. An lvalue or xvalue is an expression that refers to such an object. Without this, the compiler will complain that you "cannot bind non-const lvalue reference of type 'std::string&' to an rvalue. Then std::forward<SomeClass&> (element) will be invoked, and the instantiation of std::forward would be. So, the conversion from a A rvalue to something that P&& would accept in (1) calls the user defined conversion function operator P() &&. If an lvalue or xvalue is used in a situation in which the compiler expects a (prvalue) rvalue, the compiler converts the lvalue or xvalue to a (prvalue) rvalue. , cv1 shall be const), or the reference shall be an rvalue reference. 1/2 (your. Although the syntax of a compound literal is similar to a cast, the important distinction is that a cast is a non-lvalue. Forwarding references are a special kind of references that preserve the value category of a function argument, making it. If the operator accepts paramters by value, whenever you use an lvalue expression, there needs to be lvalue-to-rvalue conversion, which is copy initialising the parameter object from the argument. e. Let's look at the following snippet: So we have a reference being initialized by an xvalue of type const foo. It's not an rvalue reference, but a forwarding reference; which could preserve the value category of the argument. X& r = X(99); // ERRORI use forward declaration here to pass object of class B as parameter in class A. Let’s turn it around a bit. But it is still a reference, which is a lvalue. But in this particular case, the rules. This example might clarify it:So we have a reference being initialized by an xvalue of type const foo. Each expression has some non-reference type, and each expression belongs to exactly. rvalues are defined by exclusion. void f(A *&&p) {} function which accept rvalue ref to pointer which points to A; but p is still lvalue which has type r-value reference to a pointer, so u have to "cast"(std::move - does nothing just cast l-value to r-value) std::shared_ptr(std::move(p));C++ Function taking lvalue and rvalue parameters transparently. assign values to the reference return type directly in c++. The first constructor is the default one. However, a (prvalue) rvalue cannot be converted implicitly to an lvalue or xvalue, except by user-defined conversions. i is named object, so it is lvalue. One more step. From C++11 4. rvalue — The expression that refers to a. If t returns a local variable, then you get a dangling reference, since that variable is gone after the call. The right constructors for the first two cases are called. OK. As regards the concept, notice that there's no argument-parameter pair on the value level. You do not need workaround on how to use rvalue as lvalue, but rather fix your code that you do not need this workaround. As long as no const is involved, the expression T() is a modifiable rvalue, to be more precise. i by itself is an lvalue. To convert an rvalue to an lvalue, you can use this lvalue helper function: template<class T> T& lvalue_ref (T&& x) { return x; } And then the call becomes: scan (lvalue_ref (std::ifstream ("myfile")), lvalue_ref (Handler ())); This is safe as the temporaries (the ifstream and Handler) aren't destructed until the end of. 3. > In general, if I need an rvalue and it's legal to convert the lvalue I have into an rvalue, the compiler should do it automatically. Being an lvalue or an rvalue is a property of an expression. call]/12, [expr. 2 indicates the behavior of lvalues and rvalues in other significant contexts. No temporary is created, no copy is made, no constructors or. Using lvalue references where rvalue references are required is an error: int& func2(){//compilation error: cannot bind. Once an entity has a name, it is clearly an lvalue! If you have a name for an rvalue reference, the entity with the name is not an rvalue but an lvalue. e. Thus, this syntax is now legal: T&& r = T(); rvalue references primarily provide for the following: Move semantics. Once a move constructor is called upon the reference, the original object should be reset to the origin state, and so does any reference to it. Hence, values bound to an rvalue reference can be moved from (not necessarily always going to be moved from, but it is allowed), and lvalues can be bound to lvalue references and can't be moved from. Write a function template to convert rvalues to lvalues: template<typename T> T &as_lvalue (T &&val) { return val; } Now, use it: deref (&as_lvalue (42)); Warning: this doesn't extend the lifetime of the temporary, so you mustn't use the returned reference after the end of the full-expression in which the temporary was. std::move() is a function used to convert an lvalue reference into the rvalue reference. – int a = 1; // a is an lvalue int b = 2; // b is an lvalue int c = a + b; // + needs rvalues, so a and b are converted to rvalues // and an rvalue is returned. However, you don't have double && in your code, you have U && for a deduced U. We create two types of access: one const and one not const. Template argument deduction deduces T to be X, so the parameter has type X&&. Lvalues and rvalues are fundamental to C++ expressions. Note that by binding a temporary to a rvalue-reference (or a const reference) you extend its lifetime. 3 Viable functions (4). Regarding the second question. The result of std::move is an xvalue [1], which is a type of glvalue; and converting a glvalue to an lvalue reference with reinterpret_cast appears to be allowed by the wording. L-value: “l-value” refers to memory location which identifies. auto (* p) [42] = & a; is valid if a is an lvalue of type int [42]. I don't really understand why an rvalue and a non-modifiable lvalue would be the same. Read it along with, §4. So a class that doesn't support move semantics will simply do a copy instead. 1 Lvalue-to-rvalue conversion paragraph 1 and says (emphasis mine going forward): A glvalue (3. Does template argument resolution convert L-values to R-values or like how does this work? c++; c++11; templates;. Open the project's Property Pages dialog box. Follow. In the previous lesson ( 12. rvalue references are marked with two ampersands (&&). The "l" and "r" in "lvalue reference" and "rvalue reference" refers to the categories of values to which the reference can bind, not to the category of the id-expression naming a variable of this reference type. static_cast can do other things, as listed in 5. 1:. Whenever an lvalue appears in a context where an rvalue is expected, the lvalue is converted to an rvalue; see 4. 3. You don't need universal reference here const T& source is enough and simpler. . c++ base constructor lvalue to parameter. lvalue cannot be a function, expression (like a+b) or a constant (like 3 , 4 , etc. When you have a named value, as in . ; The value of i is implicitly converted to integer by constructor. In int *p = &x;: x is an lvalue, referring to the variable of that name, &x is an rvalue, it's part of the initializer (specifically, an assignment-expression ), p is neither an rvalue nor an. Rvalue references work in principle similarly to Lvalue references: We declare them by writing the data type of the rvalue followed by && and an identifier. An lvalue (so called, historically, because lvalues could appear on the left-hand side of an assignment. If you pass an argument to a reference type parameter (whether lvalue or rvalue reference), the object will not be copied. Both of g and h are legal and the reference binds directly. e. std::forward is a conditional std::move. It could be an rvalue of course, but it doesn't have to be. Sorted by: 1. During reference initialization, where the reference to cv1 T is bound to the lvalue or rvalue result of a conversion from the initializer expression from the class type cv2 S,. Most operators require lvalue-to-rvalue conversion because they use the value of the object to calculate a result. int&& x = 3; x is now an lvalue. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression; vector has two overloads of assignment operator, one for Lvalue reference. But in the circumstances of the linked question, the template instantiation of std::function cannot be inferred from the lambda type. It can convert between pointers. , with extensions: pointer or reference to a is additionally allowed to be cast to pointer or reference to unambiguous base class (and vice versa) even if the base class is (that is, this cast ignores the private inheritance specifier). Temporary materialization thus occurs in both of the OP's examples: The first temporary (with value 10) will be. C++ 中有两种类型的表达式:. But then i got following error: "Cannot. This is a changeable storage location. Set the Enforce type conversion rules property to /Zc:rvalueCast or /Zc:rvalueCast. – NathanOliver. foobar () is an rvalue because foobar () returns int. , buggy). The rvalue-reference version can't be called with an lvalue argument. So, clearly the value ’8′ in the code above is an rvalue. An lvalue-to-rvalue conversion (converting the name of the object x to its value 2. In the second case that I've reported, in whch aString is A constructor is an LValue reference, the std::move operator will still convert it to an RValue reference and I should still. Every expression in C and C++ is either an lvalue or an rvalue. This isn't strictly true in all cases; in unevaluated. The expression 0 is. Variables of type rvalue reference have to be initialized in their definition like variables of type lvalue reference. Value categories. Rvalue references are a feature of C++ that was added with the C++11 standard. @eerorika In your example y is an int, so it qualifies for rvalue conversion on return. Refer to the Essential C++ blog for RAII. 1 for an lvalue-to-rvalue conversion. Found workaround how to use rvalue as lvalue You do not need workaround on how to use rvalue as lvalue, but rather fix your code that you do not need this workaround. C. Lvalue-to-rvalue conversion C++. 5 Reference binding (3) and 12. This example might clarify it: 16. It shouldn't. An lvalue does not necessarily permit modification of the object it designates. The idea is that if you have a reference binding that could have been a direct binding if only the reference were of the appropriate kind (i. 2. If an lvalue or xvalue is used in a situation in which the compiler expects a (prvalue) rvalue, the compiler converts the lvalue or xvalue to a (prvalue) rvalue. The output is: Copy constructor with lvalue reference. thus, this is legal: string&& s = foo (); // extends lifetime as before s += "bar"; baz (std::move (s)); // move the temporary into the baz function. Set the Enforce type conversion rules property to /Zc:rvalueCast or. Whether it’s heap or stack, and it’s addressable. When the template gets resolved, baz is going to be either an lvalue or an rvalue reference, depending on the call situation. What you're referring to is the fact that if an expression. As for why the compile fails when you omit the move: When Stream& operator<< (Stream& s, Dummy) is called without the move, Stream will be std::fstream. There is no implicit conversion as suggested in the title, the reference binds directly to the. As @IgorTandetnik said - anything with a name can be assumed an lvalue. 4 — Lvalue references to const. The compiler will synthesize a move constructor only for such class that doesn't define any of its own copy-control members (copy-constructor, copy-assignment, or destructor), and if all the non- static members can be moved. Read 5. (An xvalue is an rvalue). 2) If target-type is an rvalue reference type, static_cast converts the value of glvalue, class prvalue, or array prvalue (until C++17) any lvalue (since C++17) expression to xvalue referring to the same object as the expression, or to its base sub-object (depending on target-type). init. 3. , values that can be assigned: namespaces, for instance, are not assignable; thanks to @Maggyero for the edit suggestion). If you wanted to move an lvalue, you would likely have to use an RAII container that does this for you. An lvalue is an expression that designates (refers to) an object. What makes rvalue references a bit difficult to grasp is that when you first look at them, it is not clear what their purpose is or what problems they solve. void f2(int&& namedValue){. here, X is copied into a temporary tuple, then the copy is passed to thread_exrcutor as a rvalue. See note at the end of this answer. the deprecated conversion from string literals to char* is a good example of why the rules make a lot of sense. In C++, each expression, such as an operator with its operands, literals, and variables, has type and value. [2] Then, the resulting value is placed in a temporary variable of type T. double && does not work for lvalues. rvalue references allow automatic moving/copying based upon context (for example the moving of a temporary) trying to simulate this with an lvalue style copy constructor (which actually performed a move) would likely be disastrous. References in C++ are nothing but the alternative to the already existing variable. Function to pointer An lvalue that is a function can be converted to a C++11 (prvalue) C++11 rvalue that is a pointer to a function of the same type, except when the expression is used as the operand of the &(address) operator, the () (function call) operator, or the sizeof operator. const A& x = 1; //compile x = 2; //error! A&& xxx = 1; //compile A& xx = 1; //does not compile. 1) Two possibly multilevel pointers to the same type may be converted between each other, regardless of cv-qualifiers at each level. That works well with normal variables but uint8Vect_t(dataBlock. 1) If the reference is an lvalue reference. Since the type of a is not an int, it cannot match the type that b. If the C-value is 0. That being said, and assuming you don't want to overload doStuff (otherwise see Hinnant's answer), you can write a utility. If we have a lvalue we can return it from a function, so we get a rvalue. 3 -- Lvalue references ), we discussed how an lvalue reference can only bind to a modifiable lvalue. The quote doesn't say anything about the result of &, which in fact is an rvalue. Share. 2. const foo&& can only bind to an rvalue, but const foo& can bind to both lvalues and rvalues. Forwarding references are very greedy, and if you don't pass in the exact same type (including. The addition operator + (and all other binary operators) requires both operands to be rvalue, and the result is rvalue. 2), then: the value contained in the referenced. If you compile with /W4 then the compiler will warn you. From reference - value categories. 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). universal reference. C Server Side Programming Programming. If an lvalue or xvalue is used in a situation in which the compiler expects a (prvalue) rvalue, the compiler converts the lvalue or xvalue to a (prvalue) rvalue. Answer below is for C++14. I think it's reasonable to call print_stream like this:. It's long-lived and not short-lived, and it points to a memory location where 1 is. The implementation of the language level is based on IBM's interpretation of the standard. 1. g. lvalue VS rvalue. First the compiler performs an implicit array-to-pointer conversion for "abc", so the type of "abc" becomes const char*. Note that this must wait until construction is complete for two reasons. ”. However, it's type will be const std::string or std::string depending on the choice of const in the MyPair type. enum type init and assignment must be enum inside,so enum type can't is lvalue。. An lvalue can be converted to an rvalue. For example in the following instructions. Creating a temporary object is usually not the desired behavior. func) standard conversions are performed on the the expression v. h and move. If T is non-void, then the parameter is the T (or possibly an rvalue or const lvalue reference to T) with which to initialize the wrapper. But in this particular case, the rules. uint8Vect_t encodeData(uint8Vect_t &dataBuff); Here you are taking a reference to a uint8Vect_t. an rvalue reference). lvalue references are marked with one ampersand (&). 11 for the exact listing what the cast can do; what that section doesn't list, it can't do. init. 1: A glvalue of a non-function, non-array type T can be converted to a prvalue. 左值(lvalue):指向内存位置的表达式被称为左值(lvalue)表达式。. e. As shown in the code below, by using move()funciton, when I bound a converted lvalue to an rvalue reference, and then changed the value of the rvalue. 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. You need to pass in an rvalue, and for that you need to use std::move: I can see why this is counter-intuitive! x is lvalue (as we know it). Overload resolution is usually done in terms of a strict partial. If you would fix the copy constructor to: DriverPoint(const DriverPoint& driverPoint) both adding lvalue and adding rvalue to the vector by calling push_back would work, but both would go through the copy ctor and not through move, as you didn't implement move and the default move is implicitly deleted if you declare any single one. The initializer for a const T& need not be an lvalue or even of type T. 2) returning a reference type. An rvalue is any expression that isn't an lvalue. You decided to add a move. 1 Answer. Like this: template <typename T> void foo (T &&value) { f (std::forward<T> (value)); } Here, T &&value is called a forwarding reference (as long T is deduced by the compiler. Using lvalue or rvalue qualifiers to construct a correct interface for lvalue or rvalue objects is just the same as using const, and it should be approached the same way- each function should be considered for restriction. 3=i; is illegal. Lvalue and rvalue are expressions that identify certain categories of values. For the second overload, it would call operator const P&() const&. There's no benefit in this case. You will often find explanations that deal with the left and right side of an assignment. Assignment to an rvalue doesn't really make sense, so it should be forbidden. 4. And there is no mandated lvalue-to-rvalue conversion. When C++11 invented rvalue references, none of this behavior changed at all. Roughly, it’s an lvalue if you can “take its address”, and an rvalue otherwise. 2) Lvalue of any type T may be converted to an lvalue or rvalue. If the type is a placeholder for a deduced class type, it is replaced by the return type of the function. A function parameter such as T&& t is known as a forwarding reference. Or the compiler could convert said references to pointers, push a pointer on the stack, pop the identical pointer off, and call it std::move. ref]/5. lval] 1. 1. The copy constructor uses the lvalue references which are marked with one ampersand (&) while the move constructor uses the rvalue references are marked with two ampersands (&&). For example, this means, that when rvalue reference is passed to a function, an lvalue reference overload will be chosen: T&& x=T(); f(x); Links: C++ lvalue rvalue xvalue glvalue prvalue Value categories in C++ 17 Value categories. 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. std::get returns an lvalue reference if its tuple argument is an lvalue. Numeric literals, such as 3 and 3. static_cast<X &&> Once we have an expression of a value category, we can convert it to an expression of a different value category. That's an exception to the general rule that it is impossible for lvalues to be bound to rvalue. An rvalue can also be bound to a const lvalue reference, i. Since int() isn't an lvalue, you can't assign to int(). Similarly, rhs in Gadget. C++0x rvalue reference template argument deduction. , Circle c3 (Circle (4)), I'd expect the third constructor, (copy constructor with rvalue referecne) to be called but it's not the case. When you convert 99 to type X, the result is an rvalue. The reference could be bound to the result of the implicit conversion if it wasn't non-const because the result of that implicit conversion is an rvalue i. The rvalue reference is bound to the temporary materialized from the prvalue conversion of arr. To convert an lvalue to an rvalue, you can also use the std::move() function. I could have used std::move to convert the lvalue to rvalue reference and the call would be successful. 9/1: The result of the expression static_cast<T> (v) is the result of converting the expression v to type T. To declare an lvalue reference type, we use an ampersand (&) in the type declaration: int // a normal int type int& // an lvalue reference to an int object double& //. C++0x: rvalue reference versus non-const lvalue. Temporary lifetime extension does not pass through functions so there is no way to get a lvalue from the rvalue you pass to the function. Since your t variable is an lvalue, std::apply calls product with an int& instead of an int&&. This is because, in C programming, characters are internally stored as integer values known as ASCII Values. Here’s a much more concise rundown (assuming you know basic C++ already): Every C++ expression is either an lvalue or rvalue. Fibonacci Series in C++. So, the conversion from a A rvalue to something that P&& would accept in (1) calls the user defined conversion function operator P() &&. return 17;} int m=func2(); // C++03-style copying. Both of these options are user-defined conversion functions, so neither is better in terms of overload resolution, thus an ambiguity. The confusion you're having is pretty common. In fact, that's the origin of the names: an lvalue was (originally) anything that could appear on the Left side of an assignment, and. The C++ language says that a local const reference prolongs the lifetime of temporary values until the end of the containing scope, but saving you the cost of a copy-construction (i. In return w, the implicitly movable entity w is treated as an rvalue when the return type of the function is RRefTaker as in example three, but it is treated as an lvalue when the return type of the function is Widget && as in example four. 0. That means you can't call non-const functions on the object, but if you want to pass rvalues such as temporaries, then calling non-const functions wouldn't necesarily make much sense anyway. Variables are lvalues, and usually variables appear on the left of an expression. Compiled with "g++ -std=c++0x". The reason why you need to const is to make x not a forwarding reference. for efficient. So I know why the compiler is complaining (because of trying to bind rvalue to lvalue reference -- at least this is what I think is happening -- please correct me if I am wrong). Types shall not be defined in a reinterpret_cast. template <typename element, unsigned int size> class array { private. As well as the potentially dangling lvalue references you've identified, this led in C++03 to the situation where operator<< on a temporary ostream could be called with a char (member function operator) but not with a string (free operator); C++11 fixes this with free operator overloads for rvalue references and rvalue *this overload for member. So in your example, the expression to the right of the = is an expression that happens to be an lvalue. Yes. 6) An lvalue (until C++11) glvalue (since C++11) expression of type T1 can be converted to reference to another type T2. end()) is a temporary object and cannot be bound to lvalue reference. As we've seen earlier, a and b are both lvalues. type. If an lvalue-to-rvalue conversion were performed on s, it would also call the copy constructor; [conv. The new version creates a temporary of type double for the conversion int -> double and binds. cond]/7. The value category of a compound literal is lvalue (its address can be taken). Every lvalue is, in turn, either modifiable or non-modifiable.