Can I make a dilettantish suggestion, please?
How about:
auto a1{}; // ill-formed
auto a2 = {}; // ill-formed
auto a3{10}; // int
auto a4 = {10}; // int
auto a5{10, 11}; // ill-formed
auto a6 = {10, 11}; // ill-formed
auto a1{{}}; // ill-formed
auto a2 = {{}}; // ill-formed
auto a3{{10}}; // initializer_list<int>
auto a4 = {{10}}; // initializer_list<int>
auto a5{{10, 11}}; // initializer_list<int>
auto a6 = {{10, 11}}; // initializer_list<int>
Pros:
Expressiveness: There's still a way to deduce initializer_list<T>
Future consistency: The same approach could, probably, be used to solve the evolution issue 109 (Core issue 1564, Template argument deduction from an initializer list)
Consistency: There are no surprising differences between direct-list-initialization and copy-list-initialization
Consistency 2: There are no surprising differences between initializing auto with list-initialization and other forms of initialization
Consistency 3: Currently list initialization with initializer_list can also be written in double-braced form
Cons:
Backward compatibility: More code is broken compared to N3912 (according to N3912 Chandler Carruth can measure the exact amount of broken code). I guess such code mostly lives in examples, tutorials and, may be, tests.
Rationale:
Braces {} in braced-init-lists try to denote two different things:
1) Tuple of heterogeneous arguments of "generalized constructor" (gc-braces)
2) List of homogeneous elements of initializer_list container (il-braces)
While it works when no type deduction is performed (more or less, not with templates), two notions should be separated when deducing a type.
(Step 1) Lets look at some braced-init-list we want to deduce a type from: {content}.
The outer braces are always gc-braces, and the whole braced-init-list represents a tuple of arguments.
Let "deduced type" of this tuple is the type of its content (lets call it unbraced braced-init-list).
Thus, singleton tuple of arguments is equivalent to its only argument for the purpose of type deduction (as in other forms of auto: auto b(10); auto b = 10;).
And other n-tuples (n=0, n>=2) have no deduced type.
(Step 2) Now we have unbraced braced-init-list and should deduce its type.
If unbraced braced-init-list is braced (il-braces), then it's an initializer_list and we go to Step 1 and deduce the types of its elements to deduce its type.
Otherwize it's some expression and we just deduce its type.
So, again with rationale:
// gc-braces
auto a1{}; // ill-formed: construct (gc-braces) what?
auto a2 = {}; // ill-formed: construct (gc-braces) what?
auto a3{10}; // int: construct (gc-braces) int
auto a4 = {10}; // int: construct (gc-braces) int
auto a5{10, 11}; // ill-formed: construct (gc-braces) what?
auto a6 = {10, 11}; // ill-formed: construct (gc-braces) what?
// il-braces inside of gc-braces
auto a1{{}}; // ill-formed: construct (gc-braces) initializer_list (il-braces) of what?
auto a2 = {{}}; // ill-formed: construct (gc-braces) initializer_list (il-braces) of what?
auto a3{{10}}; // initializer_list<int>: construct (gc-braces) initializer_list (il-braces) of int
auto a4 = {{10}}; // initializer_list<int>: construct (gc-braces) initializer_list (il-braces) of int
auto a5{{10, 11}}; // initializer_list<int>: construct (gc-braces) initializer_list (il-braces) of int
auto a6 = {{10, 11}}; // initializer_list<int>: construct (gc-braces) initializer_list (il-braces) of int
// bonus: a lot of braces
auto a7 = {{{10}}}; // initializer_list<int>: construct (gc-braces) initializer_list (il-braces) of type deduced from {10}, i.e. int
auto a8 = {{{{10}}}}; // initializer_list<initializer_list<int>>: construct (gc-braces) initializer_list (il-braces) of type deduced from {{10}}, i.e. initializer_list<int>
P.S.: In any case this issue should not be discussed in separation from the evolution issue 109
P.S.2: I hope everything I wrote is not a complete nonsense