Non const lvalue references
That is because a temporary can not bind to a non-const reference.
double &m = a;
a
is of type int
and is being converted to double
. So a temporary is created. Same is the case for user-defined types as well.
Foo &obj = Foo(); // You will see the same error message.
But in Visual Studio, it works fine because of a compiler extension enabled by default. But GCC will complain.
cannot bind non-const lvalue reference of type 'Node&' to an rvalue of type 'const Node'
The problem is that the function delete_node
has its first parameter as a reference to non-const Node
while the function get_node
returns a Node
by value. This means that the call expression get_node(2, &node1)
is an rvalue. But since, we cannot bind a reference to non-const Node
to an rvalue of type Node
, you get the mentioned error.
One way to solve this is to change the return type of get_node
to Node&
as shown below:
//--vvvvv------------------------------------------------>return type changed to Node&
Node& get_node(size_t position, Node *current_node){
//other code as before
return *current_node;
}
Why does this code give the error cannot bind non-const lvalue reference of type ‘char*&’ to an rvalue of type ‘char*’
The reason is that the C++ standard doesn't allow non-const references to bind to temporaries, and std::string::data
returns a pointer by value. Only const
reference can do that, and prolong the life of the temporary object.
In your case you either need to make your reference const.
const auto& r = p.data();
Or better, just create a variable that will store the pointer for you, as pointers are cheap to copy around.
const char* r = p.data();
non-const lvalue reference to type '' cannot bind to a temporary of type ' *'
At least use the const qualifier
void addMyclass( const myclass& myclassobject){
mMyQueue->push(myclassobject);
}
Or overload the function like
void addMyclass(myclass&& myclassobject){
mMyQueue->push(myclassobject);
}
And instead of
mQueuetest->addMyclass(new myclass(...));
use
mQueuetest->addMyclass(myclass(...));
because the queue is declared as storing objects of the type myclass
instead of pointers to objects.
queue<myclass>* mMyQueue = ...
^^^^^^^
Also it is unclear why you are using a pointer to std::queue
as a data member.
queue<myclass>* mMyQueue = new queue<myclass>;
Just declare the data member like
queue<myclass> mMyQueue;
Here is a demonstrative program.
#include <iostream>
#include <queue>
struct myclass
{
};
class Queuetest
{
private:
std::queue<myclass> mMyQueue;
public:
void addMyclass( const myclass &myclassobject )
{
std::cout<< "void addMyclass( const myclass &myclassobject )\n";
mMyQueue.push(myclassobject);
}
void addMyclass( myclass &&myclassobject )
{
std::cout<< "void addMyclass( myclass &&myclassobject )\n";
mMyQueue.push(myclassobject);
}
};
int main()
{
Queuetest test;
test.addMyclass( myclass() );
myclass m;
test.addMyclass( m );
}
Its output is
oid addMyclass( myclass &&myclassobject )
void addMyclass( const myclass &myclassobject )
non-const lvalue reference to type ... cannot bind to a temporary of type
You can't.
The C++ standard does not allow the binding of an anonymous temporary to a reference, although some compilers allow it as an extension. (Binding to a const
reference is allowed.)
Aside from the workaround you already have, if you can change the function to take const QImage&
then that would be better.
non-const lvalue reference type _normal_iterator cannot bind a temporary of type _normal iterator in gcc
begin
does not return a reference. It returns an iterator, which is itself an object, by value. Therefore player_hands.begin();
is a temporary. Temporaries can not be bound to non-const lvalue references.
What you can do is either of the following:
auto hand_it = player_hands.begin();
const auto& hand_it = player_hands.begin();
auto&& hand_it = player_hands.begin();
What you should use is the first case. Although the lifetime of the temporary will be extended in the other two cases, there is no need to use references at all. The second case also limits the usability, because it makes the iterator const
, making it impossible to e.g. hand_it++
.
The iterator object itself refers to an element of the container. There is no need for references. A reference to the container element is obtained from the iterator with the indirection operator: *hand_it
Visual C++ is non-compliant with the standard in allowing binding of temporaries to non-const lvalue references. You can use the /permissive-
flag to make it compliant and issue an error message for this code.
non-const lvalue reference to type 'pair ... ' cannot bind to a temporary of type 'pair ... '
That's because try_emplace
returns a pair<iterator, bool>
, which is a temporary, NOT a reference to the inserted element. See description on cppreference
After emplacing, you could say
auto& elem = connections["test"];
or
auto [connection, inserted] = connections.try_emplace("test");
auto& elem = *connection;
for example, to get a reference to the element.
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.e. the first version essentially returns second
of said pair directly.
const auto&
compiles because it is legal to declare a const
reference to a temporary, but not a non-const
lvalue reference.
I want to bind a a non-const lvalue reference to type T to a temporary of type T
You can define a auxiliary function, the "opposite" of std::move
template<typename T>
constexpr std::remove_reference_t<T> &stay(T &&t) { // perhaps "temporary" is a better name
return t;
}
In your case, the prvalue will materialize into an xvalue that binds to an rvalue reference, which lets us construct an lvalue referring to the same object.
foo.swap(stay(getBar());
As usual, the temporary lives until the end of the full-expression (to the semicolon), so this is safe (assuming swap
doesn't try to save the reference somewhere).
error: cannot bind non-const lvalue reference of type ‘Position&’ to an rvalue of type ‘Position’
Your update()
is looking to take a Position
by reference so that it can make modifications and have them percolate back to the object you're passing. However, tortoise->getCurrPos()
returns a Position
copy. If you want the changes in update()
to affect your tortoise
's Position
member, you'll need to have getCurrPos()
return its Position
by reference.
Position Runner::getCurrPos() {
Should become
Position& Runner::getCurrPos() {
For more, you can read up at What is a reference variable in C++?
Related Topics
Simple Illumination Correction in Images Opencv C++
C++ System() Not Working When There Are Spaces in Two Different Parameters
Why Are Rvalues References Variables Not Rvalue
Using \ in a String as Literal Instead of an Escape
Can a Recursive Function Be Inline
":" (Colon) in C Struct - What Does It Mean
Returning a Pointer of a Local Variable C++
Check If a String Is Palindrome
Qt: Resizing a Qlabel Containing a Qpixmap While Keeping Its Aspect Ratio
Undefined Reference to Vtable. Trying to Compile a Qt Project
Why Does the Free() Function Not Return Memory to the Operating System
Why Is Stack Memory Size So Limited