C
Mir scheint, g++ könnte recht haben. Bei einer oberflächliche Suche habe ich jedenfalls http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html keine offenen Probleme bei gefunden, die auf diese Situation anzuwenden wären. Evtl. sollten noch die Bug-Tracker der Compiler durchsucht werden.
Meine vorläufige Interpretation:
N4659 schrieb:
17.8.2.1 Deducing template arguments from a function call [temp.deduct.call]
1 Template argument deduction is done by comparing each function template parameter type (call it P)
that contains template-parameters that participate in template argument deduction with the type of the
corresponding argument of the call (call it A) as described below. If removing references and cv-qualifiers
from P gives std::initializer_list<P'> or P'[N] for some P' and N and the argument is a non-empty
initializer list (11.6.4), then deduction is performed instead for each element of the initializer list, taking P'
as a function template parameter type and the initializer element as its argument, and in the P'[N] case, if N
is a non-type template parameter, N is deduced from the length of the initializer list. Otherwise, an initializer
list argument causes the parameter to be considered a non-deduced context (17.8.2.5).
[...]
4 In general, the deduction process attempts to find template argument values that will make the deduced A
identical to A (after the type A is transformed as described above). However, there are three cases that allow
a difference:
(4.1) — If the original P is a reference type, the deduced A (i.e., the type referred to by the reference) can be
more cv-qualified than the transformed A.
[...]
Bezogen auf
template <typename T, std::size_t N1>
void foo(T (&&array)[N1]);
foo<double>({ 1., 2., 3 });
Obwohl in P' (=T) kein Templateparameter enthalten ist, der einer Deduktion bedarf, ist der gesamte Funktionsparameter ein Kontext in dem deduziert werden muss (wir müssen ja N1 ermitteln). Und nachdem N1 ermittelt wurde (aus der Anzahl der Element der Initialisiererliste), wird nicht abgebrochen: es muss immer noch für jedes individuelle Element der Liste geprüft werden, ob es (im Wesentlichen, bis auf die üblichen minimalen Transformationen) mit dem "deduzierten" Element identisch ist - obwohl dieses "deduzierte" Element tatsächlich identisch mit dem explizit angegebenen Templateargument ist, und gar nicht vom jeweiligen Element in der Initialisiererliste abhängt.
Wenn wir annehmen, dass das Ergebnis nicht beabsichtigt ist, würde ich den Defekt in dem Satz
If removing references and cv-qualifiers
from P gives std::initializer_list<P'> or P'[N] for some P' and N and the argument is a non-empty
initializer list (11.6.4), then deduction is performed instead for each element of the initializer list, [...]
verorten. Im ursprünglichen Text für C++11 konnte die Arraygröße noch nicht deduziert werden, und da war das ok so (den Fall P'[N] gab es nicht). Mit der Erweiterung auf Arrays wurde aber dann versäumt, die Deduktion für die einzelnen Elemente nur dann durchzuführen, wenn P' selbst abhängig ist (bei initializer_list<P'> ist das ja immer der Fall).
Clang zieht sich möglicherweise darauf zurück, dass ja gleich der erste Satz sagt:
Template argument deduction is done by comparing each function template parameter type (call it P)
that contains template-parameters that participate in template argument deduction with the type of the
corresponding argument of the call (call it A) as described below.
und damit die Aufforderung, die Deduktion für jedes einzelne Element durchzuführen, mangels zu deduzierender Templateparamter ins Leere läuft.