Using the constructor
T::T(int i)
via the call
a1(0)
an object of type T or const T was created.
The literal was copied via the copy constructor of build-in type int into the data-member i.
The const or non-const reference a1 or a2 can then be initialized with this newly created non-literal object.
Still cant see why T& a1(0) is not working.
A T& by itself is not an object. It merely references another object by a different name. In order to have a T&, you must also have a T (ie: a non-reference object).
Consider this:
1 2
T obj(0); // OK
T& ref(obj); // OK
Here, 'ref' and 'obj' are different names for the same object: 'obj'. If you change 'ref', you are also changing 'obj'.
With that in mind... think about what you're trying to do here:
T& a1(0);
This code makes no sense. To what object is a1 referring to? There's no T here. That's why the compiler complains.