代码之家  ›  专栏  ›  技术社区  ›  Lone Learner

为什么在类似问题上采用不同的诊断方法?

  •  3
  • Lone Learner  · 技术社区  · 6 年前

    这是我的代码:

    #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 已发出诊断。

    1 回复  |  直到 6 年前
        1
  •  3
  •   Vittorio Romeo    6 年前

    发生了两种不同的情况,如您所见,这会导致不同的诊断:

    • 在第一种情况下,您使用 复制列表初始化 找到一个 std::vector 这需要 std::initializer_lsit .

    • 在第二种情况下,您正在使用 复制列表初始化 在一 LiteralType 从而导致 集合初始化 .

    它们都应该防止缩小转换,但似乎Clang以不同的方式执行诊断。