Here is my code:
#include <vector>
int main()
{
std::vector<int> a = {1, 2.2};
}
As expected this does not compile because of the illegal narrowing conversion:
$ clang++ -std=c++11 foo.cpp
foo.cpp:5:30: error: type 'double' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]
std::vector<int> a = {1, 2.2};
^~~
Why does this compile then with only a warning?
#include <complex>
int main()
{
std::complex<int> a = {1, 2.2};
}
Here is the warning:
$ clang++ -std=c++11 foo.cpp
foo.cpp:5:31: warning: implicit conversion from 'double' to 'std::__1::complex<int>::value_type' (aka 'int') changes value from 2.2 to 2 [-Wliteral-conversion]
std::complex<int> a = {1, 2.2};
~ ^~~
1 warning generated.
I understand the notion of diagnostics and that the C++ compiler is only required to issue a diagnostic either in the form of error or warning.
But I want to be sure that I am not misunderstanding any concept here. Especially, I want to know if there is any C++ concept that I need to know why in the first case the c++11-narrowing
diagnostic was issued but in the second case literal-conversion
diagnostic was issued.
Two different things are happening, which as you can see result in different diagnostics:
In the first case, you're using copy-list-initialization and finding a constructor of std::vector
which takes an std::initializer_lsit
.
In the second case, you're using copy-list-initialization on a LiteralType
, which results in aggregate initialization.
They both should prevent narrowing conversions, but it seems that clang implements the diagnostics differently.