Short answer: No, std::reference_wrapper<T>
doesn't do that, because the differences between C++ and Python (in practice) are questions like "what goes on the heap" and "what types are immutable."
In Python, everything goes on the heap. Numbers, strings, and pointers are immutable. You cannot have pointers to variables. Python is pass-by-value, like almost every modern language.
In C++, you choose what goes on the heap. Almost anything can be modified. You can have pointers to variables, pointers to the interior of objects, and you can pass large data structures by copying them. C++ is mostly pass-by-value, like almost every modern language, except you can mark some parameters as being passed by reference.
Pass-by-value, dammit!
Honestly, people make this more complicated than it really is. The problem with simply saying “pass-by-value” or “pass-by-reference” is that our intuitive understanding of “value” and “reference” does not match the technical way in which they are used here.
Here is clear evidence that Python is pass-by-value:
def func(x):
x = [4, 5, 5]
def func2():
y = [1, 2, 3]
func(y)
print(y) # prints [1, 2, 3]
The confusing part is that a beginner will think that [1, 2, 3]
is the value, but an experienced Python user will realize that [1, 2, 3]
is the contents of an object, and a pointer to that object is then passed (by value) to the function. This is where beginners trip up:
def func(x):
x[:] = [4, 5, 6]
def func2():
y = [1, 2, 3]
func(y)
print(y) # prints [4, 5, 6]
I think this is clear evidence that x
and y
are pointers to the same object. We know that x
is not a reference to y
, since assigning a new value to x
doesn't affect y
. It works the same way in C, but for some reason, people are less confused.
void func(int *x) {
x[0] = 4; x[1] = 5; x[2] = 6;
}
void func2() {
int y[3] = {1, 2, 3};
func(y);
printf("%d, %d, %d\n", y[0], y[1], y[2]);
}
The same discussion has gone down in the Java community, with the same conclusion. In Java, variables with object type contain pointers. Those pointers are passed by value. Java functions are pass-by-value. See Java is Pass-by-Value, Dammit! or Is Java “pass-by-reference” or “pass-by-value”?
"Pass-by-object-value" is an unnecessary term for people who do not understand what pointers are, and think that Python doesn't have pointers because it calls them “references” instead. Java did the sane thing and actually called them pointers in the Java spec.
The other confusing part about Python is since objects like 6.28 or "Hello, World!"
are immutable, you can't tell the difference between passing the object contents by value and passing the pointer by value. (And CPython is only one implementation.)
What is std::reference_wrapper<T>
for?
The only funny thing going on here is that C++ has two types of pointers. Some pointers are called “pointers” and some are called “references”. They are are the same underlying concept, expressed differently. The purpose of std::reference_wrapper<T>
is to make something that is like a C++ reference but can be reassigned. Or, if you prefer, something that is like a C++ pointer but it cannot be NULL. In the end, it is still conceptually a pointer, even if you call it a reference. Or it is still conceptually a reference, even if it doesn't behave exactly like a T&
.
Just like in Python or Java, where you have pointers to objects, even if you decide to call them references.