这是我的代码:

#include <vector>

int main()
{
    std::vector<int> a = {1, 2.2};
}

正如预期的那样,由于非法缩小转换,这不会编译:
$ 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};
                             ^~~

为什么这个编译然后只有一个警告?
#include <complex>

int main()
{
    std::complex<int> a = {1, 2.2};
}

这是警告:
$ 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.

我理解诊断的概念,并且 C++ 编译器只需要以错误或警告的形式发出诊断。

但我想确保我没有误解这里的任何概念。特别是,我想知道是否有任何我需要知道的 C++ 概念,为什么在第一种情况下发出了 c++11-narrowing 诊断,但在第二种情况下发出了 literal-conversion 诊断。

最佳答案

发生了两种不同的事情,正如您所看到的,这会导致不同的诊断:

  • 在第一种情况下,您使用复制列表初始化并找到 std::vector 的构造函数,该构造函数采用 std::initializer_lsit
  • 在第二种情况下,您在 LiteralType 上使用复制列表初始化,这会导致聚合初始化。

  • 它们都应该防止缩小转换,但似乎 clang 以不同的方式实现诊断。

    关于c++ - 为什么 clang 对类似问题进行不同的诊断?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50469556/

    10-11 18:10