Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ reference can be assignable?

I've been messing with references wrapped in container classes. Why is the following code legal and appear to behave correctly?

#include <iostream>

class Foo
{
public:
  Foo( int i ) : i_( i ) {}
  int i_;
};

class FooWrapper
{
public:
  FooWrapper( Foo& foo ) : foo_( foo ) {}
  Foo& foo_;
};

int main( int argc, char* argv[] )
{
  Foo foo( 42 );
  FooWrapper fw( foo );
  FooWrapper fw2 = fw;
  std::cout << fw2.foo_.i_ << std::endl;
  return 0;
}

In the absence of an explicit operator=, I believe C++ does a memberwise copy. So when I do FooWrapper fw2 = fw;, is this not two operations: (1) create FooWrapper fw with a default ctor followed by (2) assignment from fw to fw2? I'm sure this isn't happening, because a reference can't be created uninitialized, so is the creation of fw2 actually treated as a copy construction?

I'm sometimes unclear on the roles of copy construction vs. assignment; they seem to bleed into each other sometimes, as in this example, but there's probably some rule I'm unaware of. I'd be grateful for an explanation.

like image 995
StoneThrow Avatar asked Dec 23 '22 15:12

StoneThrow


1 Answers

Despite the = in the syntax, FooWrapper fw2 = fw; copy constructs fw2 (using the copy constructor). Neither default construction nor assignment is involved at all.

And to answer the question in the title: no, references cannot be assigned. If you wrote code that attempted to actually default construct or assign a FooWrapper, such as:

FooWrapper fw2;
fw2 = fw;

...this would fail. Officially, only a "diagnostic" is required. Unofficially, every compiler I know of would/will refuse to compile it.

like image 65
Jerry Coffin Avatar answered Jan 11 '23 11:01

Jerry Coffin