& means "by reference," which is different than "by value."
When you call a variable "by reference," you are asking for its location in memory. Therefore, you can change the value of the variable simply by calling it.
For example:
int byValue(test) {
test = 6;
return test;
}
int byReference(&test) {
test = 6;
return test;
}
int test = 4; // test = 4
test2 = byValue(test); // test = 6, test2 = 6
test2 = byReference(test); // test = 6, test2 = 6
So, it matters where we put the ampersand -- it needs to be right up against the variable we want to call by reference.
In the line int &ref1 = 1, we're setting the value of ref1 to be 1, and we're doing so by reference. For all practical purposes, it's the same as saying int ref1 = 1; since we're declaring the variable, it's new to memory; since it doesn't have a reference until we create it, asking to assign its value by reference is moot.
int & const ref2 = 1 throws an error because it's basically trying to create the same constant twice. Since it errors, ref2 does not become a constant but does get assigned a value of 1.
The reason ref3 can't be changed is that even though we are calling it by reference, we have declared it a constant, and that has priority.