Why cant this happen?

Why cant a dynamic memory allocation work with references?

I was told that references work with const pointers deep down so shouldn't this be legal code?

int &&a=new int;

My compiler says that a entity of int* cannot be used to initialize a entity of int&&?

Does that mean that the compiler thinks of them as different types except deep down a reference is implemented with a pointer?

Is this right?
I was told that references work with const pointers deep down so shouldn't this be legal code?

I think you misinterpreted what you were told. References may be implemented "under the hood" as pointers (or may not be.) But, references are never pointers. They are always references.

A car may use a particular engine for propulsion or may not. A car is not an engine.


Does that mean that the compiler thinks of them as different types except deep down a reference is implemented with a pointer?

Is this right?

Compilers don't have opinions about code. References are references. Pointers are pointers. They are different types.
int &a = *(new int);
However you still should deallocate memory yourself:
delete &a;

&&: read abour move semantic and meaning of &&.
If you use int & & a (note whitespace) it will be transformed to int & a by standard.
^ That.

Using reference to a pointer does not make the pointer delete itself.
You could as well use a pointer, or a smart pointer for obvious reasons.

But I think int&& is a valid type...?
The GCC compiler successfully compiles the following code

1
2
3
4
int main()
{
    int * &&p = new int;
}
But I think int&& is a valid type...?
int&& is a r-value reference. It is different from int&.
1
2
3
int a;
int&& x = a; //error: cannot bind 'int' lvalue to 'int&&';
int&& x = std::move(a) //std::move returns r-value refs, so it is fine 
Not that this code makes any sense...

EDIT:
The GCC compiler successfully compiles the following code
Because return type of new is r-value.
You can also do: int&& x = 5;, but you cannot:
1
2
3
int * &p = new int;
int& x = 5;
//Trying to assign r-values to l-value references 
Last edited on
@MiiNiPaa
int&& is a r-value reference. It is different from int&.


As far as I know int && is equivalent to int & in the following code snips.

int x;
int &&r = x;

or

int x;
int &r = x;
Before C++11 it was, because multiple &'s were combined into single &. In C++11 && started to mean r-value reference and multiple & (like int & & & x) is now allowed only in template argument deduction stage (Info from Scott Meyers' "Overview of new C++11") or typedefs.

Edit: standard 8.5.3p5:
If T1 is reference-related to T2 and the reference is an rvalue reference, the initializer expression shall not be an lvalue. Example:
1
2
3
4
5
6
7
8
const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
double&& rrd = 2; // rrd refers to temporary with value 2.0
const volatile int cvi = 1;
const int& r2 = cvi; // error: type qualifiers dropped
double d2 = 1.0;
double&& rrd2 = d2; // error: copying lvalue of related type
int i3 = 2;
double&& rrd3 = i3; // rrd3 refers to temporary with value 2.0 

Last edited on
@MiiNiPaa

Before C++11 it was


I am speaking about C++ 11. Before C++ 11 such a code was wrong and a compiler shall issue an error.
The code snips I showed are equivalent in C++ 11.
Looks like your compiler is not standard comliant. Gcc 4.8 will issue an error (and GCC 4.7.2 too: http://ideone.com/BYkCA0 ).
I have posted standard quote above as a proof that GCC behavior there is standard compliant.
The code snips I showed are equivalent in C++ 11.


I don't know of any compilers that would agree with you. If it did work that way, std::move wouldn't be necessary for non-temporary arguments to functions that take rvalue references, which would lead to all sorts of problems.

I think you might be confusing this with how the template stuff works with regard to rvalue references.
Last edited on
In the Standard there is written that "In general, the effect of this rule is that named rvalue references are treated as lvalues" And further there is an example

A a;
A&& ar = static_cast<A&&>(a);

The expression ar is an lvalue

EDIT: Try the following code

1
2
3
4
5
6
7
8
9
void f( int &x ) { x = 10; }
 
int main()
{
    int x = 0;
    int &&r = static_cast<int &&>( x );
    
    f( r );
}
Last edited on
You are misunderstood that rvalue-references can be lvalues or rvalues depending on context but they are not stop being rvalue-references. There is some misleading naming here. Rvalue-references are just a method to implement optimal way to say "This value is not needed anymore, do whatever you like with it" and use faster implementations if told to (again explained in "Overview of new C++11"). It is just like const: you can throw it away if you want to, but why are you declared it const in first place? As compiler doesnt let you to call a member function on const object unless it explicitly defined as const, it won't let you to assign lvalue to rvalue reference until you explicitly say so (by manual cast or move()). std::move does exactly what you posted: static_cast to rvalue-reference. Two following snippets are similar in spirit:
1
2
3
4
5
6
7
8
const int x = 1;
const_cast<int>(x) = 2; //I know that I removing const here, but I need to do this

int x = 0;
int &&r = std::move(x); //or static_cast<int &&>( x ); move does almost exactly that
//I use move semantic here and I know that use of x after that will lead to undefined behavior
//I just want to make sure that fastest way of assigment will be used
//(Doesn't make sense for int, but it is intended to use on complex types after all) 
Last edited on
indeed there is some confusion in the naming because similar-sounding names are used to describe two non-overlapping concepts:

rvalue/lvalue is a quality of an expression. A type is never lvalue or rvalue. An object is never lvalue or rvalue. A function cannot "return an lvalue". value category is orthogonal to type system.

lvalue reference/rvalue reference is a property of a type. A variable (but not an object) can have lvalue/rvalue reference type. A function may return lvalue/rvalue reference. An expression never has a reference type (this is the bit that many people don't realize).
Ok thanks everyone :D
Topic archived. No new replies allowed.