15

Is it a problem to rebind a reference? I've searched this question on Google, but I can't find relevant answers to this question. What made the designers of C++ decided to make it that way?

lqr
  • 987
  • 1
  • 8
  • 11
  • 1
    because it doesn't make sense. When you assign to the reference, you assign to the object itself. – The Paramagnetic Croissant Nov 20 '14 at 10:54
  • Good (plus one) question, especially if you consider that you can contrive a situation where you get a dangling reference. – Bathsheba Nov 20 '14 at 10:58
  • What syntax would you propose for rebinding a reference? – fredoverflow Nov 20 '14 at 10:59
  • @The Paramagnetic Croissant Can't a reference in C++ acts like a reference in Java? If I have 2 objects, then I define a reference point to one object, and later I rebind this reference to the other, what can possibly go wrong? – lqr Nov 20 '14 at 11:01
  • @lqr, that's what pointers in C++ are for. Just because two different languages both use the word "reference" doesn't mean they're the same. – Jonathan Wakely Nov 20 '14 at 11:03
  • 7
    @lqr Because we have pointers and we don't need same thing twice. – Ivan Aksamentov - Drop Nov 20 '14 at 11:03
  • 1
    Note that for rebindable references, you can use [`std::reference_wrapper`](http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper): `int x, y; auto r = ref(x);` Then, rebinding to y can be done using `r = ref(y)`. (Assuming `using std::ref`) – leemes Nov 20 '14 at 11:20
  • 1
    @lqr Java references refer to objects (i.e. things), C++ references refer to variables (i.e. places that store things). They are different concepts which happen to share a name. – molbdnilo Nov 20 '14 at 11:44
  • 3
    @molbdnilo: No. C++ references definitely refer to objects. – Benjamin Lindley Nov 20 '14 at 11:48
  • @BenjaminLindley I should have stuck to "thing", as "object" also doesn't have the same meaning in C++. – molbdnilo Nov 20 '14 at 12:25
  • @The Paramagnetic Croissant At the very first glance of your comment, I didn't get what you really mean, now I understand, it's because of the ambiguity of the operator "=" when applying on references. :D – lqr Nov 20 '14 at 12:44

7 Answers7

18

Stroustrup's The Design & Evolution of C++ answers most questions of this kind. In this case, see the section §3.7 References:

I had in the past been bitten by Algol68 references where r1=r2 can either assign through r1 to the object referred to or assign a new reference value to r1 (re-binding r1) depending on the type of r2. I wanted to avoid such problems in C++.
If you want to do more complicated pointer manipulation in C++, you can use pointers.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
6

Bjarne Stroustrup introduced references into the language to support reference parameters ("call by reference") for operator overloading. You simply don't need to rebind reference parameters.

If you want "rebindable references", use pointers.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
2

In C++, a reference is just another name for an object. It is not an indirection; that's why you cannot make it point to a different object.

axiac
  • 68,258
  • 9
  • 99
  • 134
  • Mechanically, it may be an indirection (e.g. in passing by reference). But, syntactically, the step to deference a reference is not required unlike for pointers (to sound odd, reference is always syntactically de-referenced). – uvsmtid May 03 '20 at 14:37
2

Above all, "references" are actually const pointers. If you want to "rebinding", just use normal pointers.

Second, we cannot rebind references within our C++.

ref1 = ref2; // It's not mean "rebinding" - it just modify the object which ref1 points.

So, we need to make a new operator, like this

ref1 :=: ref2;

It would be a dirty point of C++, wouldn't it?

ikh
  • 10,119
  • 1
  • 31
  • 70
  • 2
    The operator `:=:` is considered to be defined as the "swap operator" in [draft N3553](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3553.pdf). – leemes Nov 20 '14 at 11:14
1

References are useful because they don't support unsafe pointer arithmetic and will never be null. On the other hand, pointers can be rebound and can be placed in STL containers. A trade off with all these useful properties is std::reference_wrapper:

#include <functional>
#include <iostream>
#include <string>

int main() {
  std::string s1 = "my", s2 = "strings";

  auto r = std::ref(s1);  // bind

  // use r.get() to access the referenced object
  std::cout << '\'' << r.get() << "' has " << r.get().size() << " characters\n";

  r = s2;  // rebind

  // use the other object
  std::cout << '\'' << r.get() << "' has " << r.get().size() << " characters\n";
}
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
1

Internally reference is nothing but a const pointer (once an address is assigned to that pointer then you can change it in a straightforward way).

int& r = a; // int* const r = &a;

The sample code below explains what will happen behind the screen.

int main() {
    int a = 10;
    int b = 20;

    int& r = a;          // = [int* const r = &a;]
    r = b;               // = [*r = b] value update. NOT address update [r = &b]
    ++r;                 // = [++*r]
    cout << r << a << b; // 21 21 20 (bcos r is NOT rebinded to b)
}
SridharKritha
  • 8,481
  • 2
  • 52
  • 43
0

One problem is the syntax. How would such an operation be written? You would have to create an entirely new operator to remove ambiguity, a pretty big investment for something that can already be done with pointers.

glank
  • 371
  • 2
  • 10