a non-const reference may only be bound to an lvalue. So in your case, you need to rewrite your. a non-const reference may only be bound to an lvalue

 
So in your case, you need to rewrite youra non-const reference may only be bound to an lvalue  an lvalue, this constructor cannot be used, so the compiler is forced to use

The basic idea behind references is that lvalue references bind to lvalues, and rvalue references bind to rvalues; the reference thus bound henceforth refers to the value it was bound to. & attr  (optional) declarator. Return by value. 上記のようなコードを書いたところ、以下の警告が出た。. 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. 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. The behaviour of this is to copy-initialize a temporary of the same type as the reference. Case 3: binding to data members. The compiler automatically generates a temporary that the reference is bound to. If you want to capture the reference you need to declare a reference. next);. has a class type. ref/6] ). cpp struct S { }; void f(S&) { } S g() { return S {}; } int main() { S& s = g (); // warning C4239 at /W4 const S& cs = g (); // okay, bound to const ref f (g ()); // Extension: error. 10 is a prvalue expression. Share. This seems to be well defined however (writing to a temporary value is just like writing to any value, the lifetime has no relevancy to the validity of. ; T is not reference-related to U. There are exceptions, however. There are exceptions, however. C++: rvalue reference converted to non-const lvalue-reference. You are returning a copy of A from test so *c triggers the construction of a copy of c. , int and const int are similar, int* const ** volatile and volatile int** const * are similar, and crucially int* and. 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 first version essentially returns second of said pair directly. png", 560, 120); int x2 = 560 + 54; int x1 = 560; int y1 = 120; int y2 = 291 + 120; const int * xSolv2 = &x2. 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. Creating a const reference does not need to be created from a lvalue variable, because if it is created from a non-lvalue variable, it creates a. The lifetime extension is not transitive through a. 3. The language forbids that sort of binding for various reasons. 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. It's fairly obvious why int &ri3 = 2; (without the const) is invalid, but that doesn't imply that const int &ri3 = 2; is valid. 15. 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. rvalue reference 는 rvalue (즉, 상수와 임시객체)도 참조가 가능 하다 점을 빼고는 기존의 참조와 동일합니다. However, you don't have double && in your code, you have U && for a deduced U. e. std::vector<bool> is special from all other std::vector specializations. This program outputs: value = 5 value = 5. hskoglund last edited by Chris Kawa . You cannot do that with a non-member function that accepts an lvalue reference. The unary & operator gets a pointer to a variable. Notably, types of expressions (i. View Site LeadersThe result is an lvalue if T is an lvalue reference type or an rvalue reference to function type (8. its address could be got). There's no difference between a bound rvalue reference and a bound lvalue reference. Note that the table indicates that an rvalue cannot bind to a non-const lvalue reference. Improve this question. rvalue Reference Cannot Bind to a Named lvalue. 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. The only way to safely bind an rvalue to an lvalue is either by marking the lvalue as const, or using a mutable rvalue reference && (introduced in C++11 believe?) Alex November 11, 2023 In the previous lesson ( 12. Since the temporary B that's returned by source () is not. The page is trying to say that you can write m. Without rvalue expression, we could do only one of the copy assignment/constructor and move assignment/constructor. " Rule 2, "A non-const reference shall not be bount to a bit-field". A temporary can only bind to const lvalue references, or rvalue references. Only expressions have values. In the second case, fun () returns a non-const lvalue reference, which can bind to another non-const reference, of course. rvalue references are marked with two ampersands (&&). R-value: r-value” refers to data value that is stored at some address in memory. For lvalue-references (that is, the type T&) there isn't. It seems a little inconsistent that adding const to a reference does more than just ban modification. CheckCollision (0. Specifically, a const rvalue will prefer to bind to the const rvalue reference rather than the const lvalue reference. 4 — Lvalue references to const. You are returning a reference to a local variable. There's no reason to make it a reference. This means the following. Some compilers allow int &r = 5; as an extension, so it makes sense, it's just not allowed by the standard. std::string&& rref = std::string("hello"); rref has value category lvalue, and it designates a temporary object. Constructor by the definition does not have a return value. Of course since methods can be called on rvalue (and thus prvalue) and those methods may return a reference to the objects they were called on we can easily bypass the silly (1) a reference is only allowed to bind to a lvalue restriction. When you pass a pointer by a non- const reference, you are telling the compiler that you are going to modify that. In this case, the conversion function is chosen by overload resolution. Confusion between rvalue references and const lvalue references as parameter. 1 invalid initialization of non-const reference of type from an rvalue of type. 12. doesn't that mean that an rvalue ref is an lvalue. Even Microsoft engineers like u/STL recommend avoiding this "extension" if I recall correctly. e. Troubles understanding const in c++ (cannot bind non-const lvalue reference) 0. 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. 4 Why Rvalue cannot bind Lvalue reference? 18 Invalid initialization of non-const reference of type. This example is very similar to the previous one, except the temporary object is non-const this time. This constness can be cast away with a const_cast<>. Thus you know that you are allowed to manipulate it without damaging other data. rvalues can be residing on read-only memory spaces where changing them might not be allowable and hence the compiler prohibits them. h"` displayPNG("solve. In this case, the conversion function is chosen by overload resolution. 1. 3. 3/5. In contrast you can bind const references to temporary values as in: std::string const & crs1 = std::string (); However the following is illegal: std::string & rs1 = std::string (); Don't pass int&, it can't be bound to a constant or temporary because those can't be modified - use const int& instead. A temporary object may not be bound to a non constant reference. It's just that type of that lvalue is "rvalue reference to Key ". Take pointers by value -- T const*-- and things are more sane. A temporary or an rvalue cannot be changed with a reference to non-const. They could also bind to rvalues but only when the. E may not have an anonymous union member. 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). You would only need to create such a wrapper if you needed to do things with it that you can't do with C++ objects, such as storing it in an NSArray or. int const&x = 42; // It's ok. Now it makes actually sense to take its address, as it is an lvalue for all intents and purposes. So in your case, you need to rewrite your. 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. cannot bind non-const lvalue reference of type to an rvalue of type 0 Implementation of the decorator class in C++ using a member reference to the decorated object not working as expected12. 7. That is to say, usage of a reference is syntactically identical to usage of the referent. All groups and messages. v = this->v*a. name. Non-compliant compilers might allow a non-const or volatile lvalue reference to be bound to an rvalue. int global_x; void foo (int*& ptr) { ptr = &global_x; } void bar () { int local_x; int * local_ptr = &local_x; foo. Follow. 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. One const and the other non. So naming kInt is not deemed an odr-use as long as it. Follow. 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. So, despite your extra const in your reference type the language still requires it to be bound directly to i. Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i. What you want is in 40two's answer, but make sure to forward the parameter t. m. A reference to the container element is obtained from the iterator with the indirection operator: *hand_it. Change the declaration of the function GetStart like: Point & GetStart(); Also at least the function GetEnd should be changed like: Point & GetEnd(); You could overload the functions for constant and non-constant objects:It looks like we are actually able to bind temporary object to non-const reference, but only if this object. 9,096 1 33 54. It's the first const that I'm unsure of. In fact, in terms of overload resolution, an rvalue prefers to be bound to an rvalue reference than to an lvalue const reference. . reference (such as the B& parameter in the B::B (B&) constructor) can only. 2), an xvalue if T is an rvalue reference to object type, and a prvalue otherwise. So the following snippet works like a charm: const int& ref = 10; // OK!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. This won't work. You can also simplify the return expression, and make the method const, since comparing two objects should not change either of them: bool String::operator< (const String & obj) const { return strcmp (*this, obj) < 0; } although I am not sure strcmp can deal with two. 5The Lvalue refers to a modifiable object in c++ that can be either left or right side of the assignment operator. 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). Consulting the cppreference documentation for <type_traits>, it appears that there is not such a tool in the standard library. 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). Lvalue references to const can be bound to. The standard specifies such behavior in §8. The non-const subscript operator returns a non-const reference, which is your way of telling your callers (and the compiler) that your callers are allowed to modify the Fred object. Returning non-const lvalue reference. C++/SDL "initial value of reference to a non-const must be an lvalue". Const reference can be bounded to. There are two aspects to the const in C++: logical constness: When you create a variable and point a const pointer or reference to it, the compiler simply checks that you don't modify the variable via the const pointer or reference, directly or indirectly. Yes, some times it is very convenient to be able to locally modify a pass-by-value argument to a function. I dont know if its bug in compiler or is it intended. Example 51) Is actually not so arbitrary. Explanation: const lvalue indicates that the callee wants a read-only view of the object and it does not matter what type of object the caller pass as the argument. qual] or even [conv. 5. initial value of reference to non-const must be an lvalue, Passing an object type by. const char*&). 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. int const&x = 42; // It's ok. So the temporary value_type () will be bound to val and will persist for the duration of the constructor. Non-const reference may only be bound to an lvalue (2 answers) Error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’ (2 answers) If you have a temporary object that's very expensive to copy, you may prefer to take a const& to that object (say a function return) rather than copying it into another variable to use later. Non-const reference may only be bound to an lvalue. In the above program, because value parameter y is a copy of x, when we increment y, this only affects y. In other words, in your first example the types actually do match. The problem is that a non-const lvalue reference cannot bind to a temporary, which is an rvalue. m. const auto& refInstance = m_map. a. 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. VS2008 is not too bad as at least it gives a compile warning: warning C4239: nonstandard extension used : 'initializing' : conversion from std::string to std::string & A non-const reference may only be bound to an lvalue A non-const reference may only be bound to an lvalue. Second, our new version of the copy constructor will just as happily transplant the internals of lvalues: IntVector v1; IntVector v2 (v1); // v1 is no longer. Calling a non-static member function of class X on an object that is not of type X, or of a type derived from X invokes undefined behavior. a is an expression. void checkMe (shared_ptr<string>& param = shared_ptr<string> ()); This MSDN article says it is a /W4 warning. r-value simply means, an object that has no identifiable location in memory (i. Allowing non-const references to bind to r-values leads to extremely confusing code. 3 -- Lvalue references ), we discussed how an lvalue reference can only bind to a modifiable lvalue. This seems to be well defined however (writing to a temporary value is just like writing to any value, the lifetime has no relevancy to the. The second const is good, as is stops the source item being modified. A reference (of any kind) is just an alias for the referenced object. The following example shows the function g, which is overloaded to take an lvalue reference and an rvalue. For non-static member functions, the type of the implicit object parameter is — “lvalue reference to cv X” for functions declared without a ref-qualifier or with the & ref-qualifier — “rvalue reference to cv X” for functions declared with the && ref. For example, when passing things by value, or else with things like A a; B b = a;. You can normally hide the expression template type behind private members. The only time that lifetime is extended is when a prvalue (or an xvalue referring to a member of a prvalue) is bound to a reference variable, and the lifetime of the prvalue is extended to that of the variable:. The reference returned from get_value is bound to x which is an l-value, and that's allowed. In fact, if the function returns a &, const& or &&, the object must exist elsewhere with another identity in practice. 1. (An xvalue is an rvalue). The binding rules for rvalue references now work differently in one. But since it's a non-const reference, it cannot bind to an rvalue. 4. decltype(fun()) b=1; Then, your code initializes a const reference with a prvalue of a different (non-reference-related) type. GetImage (iTileId, pulImageSize, a_pImage ); With the method defined as:This change is required by the C++ standard which specifies that a non-const. What std::string::c_str returns is an rvalue, which can't be bound to an lvalue-reference to non-const (i. and not. However,. But a more proper fix is to change the parameter to a const. A operator*(const A& a) // Return a value, not a reference. Reference is always constant, you can't change reference. Once it is bound, it's just a reference. r can be bound to the conversion result of e or a base class of e if the following conditions are satisfied. 2nd that, nullptr is the best way to declare the optional parameter. Actually the Standard say so: 8. 3/5, [dcl. A variable is an lvalue, so you are allowed to bind a non const reference to it. 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. And an rvalue reference is a reference that binds to an rvalue. The only way to safely bind an rvalue to an lvalue is either by. (コンパイラは VS2012) warning C4239: nonstandard extension used : 'initializing' : conversion from 'A' to 'A &' A non-const reference may only be bound to an lvalue. What I have seen however is that you can bind an rvalue to an rvalue reference and since a named rvalue reference is inherently an lvalue, you can bind it to an lvalue reference. Change the declaration of the function GetStart like: Point & GetStart(); Also at least the function GetEnd should be changed like: Point & GetEnd(); You could overload the functions for constant and non-constant objects: You may say, "ha, that's allowed because we want to provide the programmer with some flexibility to do "stupid" things that are in fact not that stupid", which is the reason I can hardly buy because if I buy this excuse, I think that "binding temporary to non-const lvalue reference" can be justified using the same reason. To handle other value categories, one may use std::forward_as_tuple:. In your default constructor, you try to assign a temporary value (the literal 0) to it, and since it's a reference type you can't give it a temporary value. e. But if you are asking why this doesn't. To reduce template instantiation overhead, I would recommend a more direct implementation:will result in output: Constructor called 42. , temporary) double but a temporary cannot be bound to a non-const reference. find (key); But this returns an iterator. 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. I believe the relevant Standard paragraph is 8. You normally point to some spot in memory where you stored a value of interest. Would you explain why you need a non-const reference that cannot bind to non-const objects?. an lvalue, this constructor cannot be used, so the compiler is forced to use. Regarding the second question. However, when you use a const reference to a non-const object, you are asking the compiler to not let you modify the object through that particular. 7. A operator*(const A& a) const { A res; res. 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). add (std::move (ct)); } A forwarding reference can bind to both lvalues and rvalues, but. (I) An rvalue had been bound to an lvalue reference to a non-const or volatile type. because if it did, at the point foo starts, it would only have a reference to the destructed remnants of what was once the farewell string. )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. const A& x = 1; //compile x = 2; //error! A&& xxx = 1; //compile A& xx = 1; //does not compile. An entity (such as an object or function) that has. Non-const lvalue reference to type '_wrap_iter' cannot bind to a value of unrelated type '_wrap_iter' c++;. r-value causes a warning without the use of std::move. non-const reference of type from an rvalue. Viewed 3k times. Let's look at std::vector for example: reference at( size_type pos ); const_reference at( size_type pos ) const; Would you look at that. For example inc(1). Since the temporary B that's returned by source () is not. (Binding to a const reference is allowed. Fibonacci Series in C++. I'll try paraphrasing it: In compiler version 2002, if the compiler had the choice if it would transform an object returned by a function to a non-const-reference or another type, it would have chosen the non-const-reference. Unfortunately, they may compile with one common compiler, due to language. Sounds like you actually want getPlayer to return a reference too and then to. 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. Note that for const auto& foo, const is qualified on the auto part, i. non-const lvalue reference to type 'const int *' cannot bind to a. Oct 10, 2013 at 22:07. 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. 0f, c); The other similar calls need to be fixed too. bind to an lvalue. it is explained that an lvalue is when you can take its address. This means the following is illegal: int main() { const int x { 5 }; int& ref { x }; return 0; } This sample shows the Microsoft extension that allows a temporary of a user-defined type to be bound to a non-const lvalue reference. Given all three functions, this call is ambiguous. " I really need some further explanations to solving this: Non-const references cannot bind to rvalues, it's as simple as that. obj & a1 = bar(); invalid initialization of non-const reference of type ‘obj&’ from an rvalue of type ‘obj’ using g++. New rvalue reference rules were set by the C++ specification. begin(), dataBlock. So the first fix is to not use the wrong technique here, and accept by an lvalue reference instead:The simple answer is that you are right in essence. r-value references are designed to be the subject of a move-constructor or move-assignment. 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). It work that way:. ref]/5: — Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i. Now, that the prvalue has an indeterminate lifetime, it is. yet you can still change the data x by modifying x. "A reference to type 'cv1 T1' is initialized" refers to the variable that is being initialized, not to the expression in its initializer. In this context, binding an rvalue to the non-const reference behaves the same as if you were binding it to a const reference. Some compilers allow int &r = 5; as an extension, so it makes sense, it's just not allowed by the standard. Non. 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. Otherwise. 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. a. Non-const reference may only be bound to an lvalue. An rvalue reference can only bind to an rvalue, which is a candidate for moving. This means the following is illegal: This is disallowed because it would allow us to modify a const variable ( x) through the non-const reference ( ref ). There are two overloads. (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). Thank you. 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. It can appear only on the right-hand side of the assignment operator. , cv1 shall be const), or the reference shall be an rvalue reference. 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. New rvalue reference rules were set by the C++ specification. Otherwise, the reference you get behaves more. A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:I can't be bothered to go looking at that code, but. 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. A non-const reference may only be bound to an lvalue[/quote] 1 Reply Last reply Reply Quote 0. 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. 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. 3 -- Lvalue references ), we discussed how an lvalue reference can only bind to a modifiable lvalue. First of all, I will post the warning I'm getting: xlist. For sure, string{""} shall have an address somewhere in memory. 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. The reference is. Non-compliant compilers might allow a non-const or volatile lvalue reference to be bound to an rvalue. ) Note that irr doesn't bind to iptr; so any modification on. , 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. In the original example , both are xvalues so the ternary operator evaluates to an xvalue. Ask Question Asked 8 years, 10 months ago. However, int can be implicitly converted to double and this is happening. 5. int & a=fun (); does not work because a is a non-const reference and fun () is an rvalue expression. C++ prohibits passing a temporary object as a non-const reference parameter. Add a comment. 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. g. It's the specific case where changing T& to const T& does more than just ban modifications. Note that there is one exception: there can be lvalue const reference binding to an rvalue. And the lvalue-reference to const could bind to. e. Since the constructor in your example only takes lvalues, you can only pass lvalues into the factory function. temporary] ( §12. This sample shows the Microsoft extension that allows a temporary of a user-defined type to be bound to a non-const lvalue reference. match. clang++ says: " error: non-const lvalue reference to type 'class foo' cannot bind to a temporary of type 'class foo'" Change foo. C++ initial value of reference to non-const must be an lvalue and I'm sure I have done everything right. Because as_const doesn't take the argument as const reference. thanks in advance, George. 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. The parameter of the function is an lvalue reference to non-const, and such references cannot be bound to rvalues 1. push() can use an if constexpr. That is to say, usage of a reference is syntactically identical to usage of the referent. 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. You can either modify the return type of the function from Value* to const Value& , or opt for return *cleverconfig[name]; . c++; Share. Use a const reference, which can be bound to rvalues. However, you might need at that returns non-const reference too. having an address). But in your case the operands are different category (123 is a prvalue, a is an lvalue). In 9. Just like how we don't want the first example to create a temporary int object (a copy of x) and then bind r to that, in the. 3. nik7. However, in VS2010 I seem to be able to do so:. then the reference is bound to the initializer expression lvalue. 3 -- Lvalue references ), we discussed how an lvalue reference can only bind to a modifiable lvalue. You have two options, depending on your intention. RVO may explain this particular quark, but you cannot return a reference to something that doesn't exist. Notes: A non-const or volatile lvalue reference cannot be bound to anrvalue of a built-in type. The reason for this is mostly convenience: It. v = this->v*a. Now, that the prvalue has an indeterminate lifetime, it is. i. an lvalue, this constructor cannot be used, so the compiler is forced to use. 2. A const reference could be bound to rvalue, and for this case, a temporary int will be created and initialized from 255. Looks like an X-Y problem. const int x = 0; int&& r = x; Here, we don't have an exact match in types: the reference wants to bind to an int, but the initializer expression has type const int. Const reference can be bounded to. In the following post: Understanding lvalue/rvalue expression vs object type. for example, to get a reference to the element.