代码之家  ›  专栏  ›  技术社区  ›  Pates

std::copy和std::vector::assign的转换警告

c++
  •  12
  • Pates  · 技术社区  · 8 年前

    std::vector<int> ,则数字必须通过某种舍入进行转换。通常这会更改数字,1.5会更改为1或2,我希望编译器至少会警告此转换。所以我用 -Wconversion g++或clang++上的标志。这将启用以下项的警告: std::vector::push_back 或者直接分配,但不是为了 std::copy std::vector::assign(iterator first, iterator end) .

    现在我的问题是:如何获得的转换警告 std::vector::assign

    下面是我的示例程序:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using source_type = std::vector<double>;
    using target_type = std::vector<int>;
    
    int main() {
        source_type vsource;
        target_type vtarget1;
        target_type vtarget2;
        target_type vtarget3;
        target_type vtarget4;
    
        // Fill source with a number
        vsource.push_back(1.5);
    
        // This will give a compiler warning as expected
        vtarget1.push_back(vsource.at(0));
    
        // This does not give a warning, why not?
        vtarget2.assign(vsource.begin(), vsource.end());
    
        // Also this does not give a warning, why not?
        vtarget3.assign(vsource.size(), 0);
        std::copy(vsource.begin(), vsource.end(), vtarget3.begin());
    
    
        // The following should be equivalent to std::copy according to
        // http://www.cplusplus.com/reference/algorithm/copy/?kw=copy
        // Here we get a warning as expected (in contrast to std::copy).
        vtarget4.assign(vsource.size(), 0);
        auto source = vsource.begin();
        auto target = vtarget4.begin();
        while (source != vsource.end()) {
           *target = *source;
           ++target; ++source;
        }
    
        std::cout << vsource.at(0)  << " "
                  << vtarget1.at(0) << " "
                  << vtarget2.at(0) << " "
                  << vtarget3.at(0) << " "
                  << vtarget4.at(0) << std::endl;
    
        return 0;
    }
    

    我编译时使用:

    g++ -Wall -Wextra -Wconversion -std=c++11 -pedantic 
    clang++ -Wall -Wextra -Wconversion -std=c++11 -pedantic
    

    我只收到两个警告,我还想再得到几个:

    question.cpp:22:24: warning: implicit conversion turns floating-point number into integer: 'value_type' (aka 'double')
          to 'value_type' (aka 'int') [-Wfloat-conversion]
        vtarget1.push_back(vsource.at(0));
    
    question.cpp:40:18: warning: implicit conversion turns floating-point number into integer: 'double' to 'int'
          [-Wfloat-conversion]
           *target = *source;
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   user32434999    8 年前

    -std=c++11 -Wfloat-conversion -Wsystem-headers

    std::copy(vsource.begin(), vsource.end(), vtarget3.begin());
    

    如你所见 here .

    然后输出

    <source>: In function 'int main()':
    
    <source>:21:34: warning: conversion from '__gnu_cxx::__alloc_traits<std::allocator<double>, double>::value_type' {aka 'double'} to 'std::vector<int>::value_type' {aka 'int'} may change value [-Wfloat-conversion]
    
    21 |     vtarget1.push_back(vsource.at(0));
    
       |                        ~~~~~~~~~~^~~
    
    <source>:38:18: warning: conversion from 'double' to 'int' may change value [-Wfloat-conversion]
    
    38 |        *target = *source;
    
       |                  ^~~~~~~
    
    In file included from /opt/compiler-explorer/gcc-trunk-20180917/include/c++/9.0.0/bits/char_traits.h:39,
    
                     from /opt/compiler-explorer/gcc-trunk-20180917/include/c++/9.0.0/ios:40,
    
                     from /opt/compiler-explorer/gcc-trunk-20180917/include/c++/9.0.0/ostream:38,
    
                     from /opt/compiler-explorer/gcc-trunk-20180917/include/c++/9.0.0/iostream:39,
    
                     from <source>:1:
    
    /opt/compiler-explorer/gcc-trunk-20180917/include/c++/9.0.0/bits/stl_algobase.h: In instantiation of 'static _OI std::__copy_move<false, false, std::random_access_iterator_tag>::__copy_m(_II, _II, _OI) [with _II = double*; _OI = int*]':
    
    /opt/compiler-explorer/gcc-trunk-20180917/include/c++/9.0.0/bits/stl_algobase.h:400:30:   required from '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = double*; _OI = int*]'
    
    /opt/compiler-explorer/gcc-trunk-20180917/include/c++/9.0.0/bits/stl_algobase.h:437:30:   required from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = __gnu_cxx::__normal_iterator<double*, std::vector<double> >; _OI = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]'
    
    /opt/compiler-explorer/gcc-trunk-20180917/include/c++/9.0.0/bits/stl_algobase.h:470:7:   required from '_OI std::copy(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<double*, std::vector<double> >; _OI = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]'
    
    <source>:28:63:   required from here
    
    /opt/compiler-explorer/gcc-trunk-20180917/include/c++/9.0.0/bits/stl_algobase.h:338:18: warning: conversion from 'double' to 'int' may change value [-Wfloat-conversion]
    
    338 |        *__result = *__first;
    
        |                  ^
    
    Compiler returned: 0