Why do gcc and clang allow me to construct an abstract class?
Because they're broken, according to the standard.
Section 10.4 defines how abstract classes work. It contains this line (in C++14):
no objects of an abstract class can be created except as subobjects of a class derived from it.
The initialization rules for references with braced-init-lists will construct a temporary and bind it to the reference. Temporaries are objects. As such, the code you wrote above will attempt to create an "object of an abstract class" as something other than a "subobject of a class derived from it."
Something the standard expressly forbids. There is no ambiguity in the standard in this regard. While 10.4, p3 does specify places that the compiler is required to out-right error if you type them (declaring abstract classes as function parameters, explicit conversions, etc), the standard still requires implementations to forbid the construction of an abstract class as something other than a "subobject of a class derived from it."
A temporary is not a "subobject of a class derived from it." And therefore, compilers are obligated to forbid this.
Any compiler which does not has a bug.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…