g++ 是否错误地抛出 -Wnarrowing?

Is g++ falsely throwing -Wnarrowing?

这是 C++14 模式下的 GCC 7.4 运行:

        size_t i = 8;
        std::string strIndent { i, ' ' };

看起来不错,但我收到警告:

AnalyticsDBI.cpp:538:48: warning: narrowing conversion of ‘i’ from ‘size_t {aka long unsigned int}’ to ‘char’ inside { } [-Wnarrowing]
                 std::string strIndent { i, ' ' };

这是一个编译器错误?我无法理解编译器如何 select 进行错误的重载。应该是构造函数2,如图here.

使用大括号更喜欢列表构造函数(这里使用 std::initializer_list<char>,cppreference 上的第 9 个)。在这个构造函数中,元素是char,所以它是一个收缩转换。如果你用 -pedantic-errors 编译,GCC 会给你一个实际的错误,而不仅仅是一个警告;这不是一个合格的程序,因为在大括号初始化中不允许缩小转换。

用 clang 编译表明它正在尝试调用 initializer_list<char> 构造函数,其中 size_t -> char 是一个缩小转换:

narrowing.cpp:5:26: error: non-constant-expression cannot be narrowed from type 'size_t' (aka 'unsigned long') to 'char' in initializer list [-Wc++11-narrowing]
        std::string strIndent { i, ' ' };
                                ^
narrowing.cpp:5:26: note: insert an explicit cast to silence this issue
        std::string strIndent { i, ' ' };
                                ^
                                static_cast<char>( )
1 error generated.

改用 () 将调用您想要的构造函数:

 std::string strIndent(i, ' ');