The reason that the narrowing conversion inside {}
are only an error in C++11 mode is simple: it isn't an error in C++03. Now, T var{value};
is new C++11 syntax, but T var = {value};
was already valid C++03 syntax, and did allow narrowing conversions.
int i = { 10.1 }; // valid C++03, invalid C++11
It makes it easier for the GCC developers to treat narrowing conversions the same in T var{value};
and T var={value};
initialisations. This is useful because it avoids two separate code paths for the warning in the compiler.
It makes it easier for the GCC developers to accept even the T var{value};
syntax in C++03 mode, merely warning about it. Several other C++11 syntax extensions are also enabled in C++03 mode. This is useful because several C++11 syntax extensions are used in GCC's implementation of the standard library (where warnings about it are suppressed).
The reason that int i{10.1};
isn't an error in GCC 4.9 in C++11 mode, but was made an error in GCC 5, is because not treating it as an error caused valid code to be rejected. The C++ standard requires treating it as an error in SFINAE contexts, and here is a valid C++11 program that runs incorrectly because of this with GCC 4.9:
#include <stdio.h>
template <typename T> void f(double) { puts("ok"); }
template <typename T, typename = decltype(T{10.1})> void f(int) { puts("error"); }
int main() { f<int>(1); }
This is supposed to print "ok". The second overload is supposed to be discarded.
With GCC 4.9, it prints "error", because the second overload isn't discarded, and int
is a better match than double
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…