当一个浮点数被插入到 std::vector<int>
中时,这个数字必须通过某种方式进行四舍五入转换。通常情况下,这会改变数字,例如1.5 会变成1或2,我希望编译器至少能警告这种转换。因此我在 g++ 或 clang++ 上使用 -Wconversion
标志。这将启用对 std::vector::push_back
或直接赋值的警告,但不适用于 std::copy
或 std::vector::assign(iterator first, iterator end)
。
现在我的问题是:如何获得关于 std::copy
和 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;
-Wsystem-headers
的内容。 - o11cstd::copy(vsource.begin(), vsource.end(), vtarget3.begin());
上的警告,但是我没有在vtarget2.assign(vsource.begin(), vsource.end());
上看到警告。不幸的是,还有太多其他的警告。如果这是正确的方法,我就迷失了 :( - Patesassign
的警告,是因为(至少在libstdc++中),std::vector::assign
最终会调用std::copy
来复制数据。因此只需要在一个地方警告转换即可。 - Miles Budnekassign
->_M_assign_dispatch
->_M_assign_aux
->_M_allocate_and_copy
-> 根据当前大小/容量,std::copy
和/或std::__uninitialized_copy_a
->std::uninitialized_copy
->std::__uninitialized_copy<false>::__uninit_copy
->std::copy
进行处理。因此,在静态情况下,有 4 次对std::copy
的调用。 - o11cpush_back
指定了需要传入一个int
,因此类型转换发生在你的代码中。但是尝试使用emplace_back
。 - o11c