如何为 std::vector 复制或使用隐式缩小转换禁用 Visual Studio 警告 C4244
Posted
技术标签:
【中文标题】如何为 std::vector 复制或使用隐式缩小转换禁用 Visual Studio 警告 C4244【英文标题】:How to disable Visual Studio warning C4244 for std::vector copy or assign with implicit narrowing conversion 【发布时间】:2017-10-23 14:15:46 【问题描述】:我想要将双精度向量转换为浮点向量。而且我不希望 Visual Studio 抛出警告 C4244,“可能丢失数据”,即缩小转换范围。
请不要发布 cmets 或回答说我不应该这样做。我知道后果。我只是想压制警告。在此特定功能范围之外禁用警告是不可接受的,例如全局通过项目设置。
我还想使用 vector::copy 或 vector::assign。使用 static_cast 通过 transform() 或 for_each() 避免警告是....对我的口味来说太明确了。所以这个问题是如何禁用警告,而不是避免它。
我的警告抑制尝试不起作用:
vector<float> DoubleVectorToFloat( vector<double> & x )
#pragma warning( push )
#pragma warning( disable : 4244 )
return vector<float>( x.begin(), x.end() );
#pragma warning( pop )
我知道禁用警告是不好的。但一种尺寸并不适合所有人。我的库是实时的,可以处理 10 的 MiB/s。我想要调用模板 _Copy_unchecked1(etc);我不想支付错误检查的性能损失。
【问题讨论】:
Visual Studio 允许在每个文件的基础上禁用警告。这不仅仅是一个特定的功能,但在您的情况下是可以接受的。 【参考方案1】:要禁用这种类型的警告,您可能必须将此函数放入它自己的模块中并禁用顶部的警告:
// top-of-file
#pragma warning( disable : 4244 )
// All your includes here
std::vector<float> DoubleVectorToFloat( std::vector<double> & x )
return std::vector<float>( x.begin(), x.end() );
// end-of-file
【讨论】:
谢谢。这回答了提出的问题。我同意@bolov 的回答,认为这是完成向量缩小转换的一般“正确”方式,但这不是我所要求的。 我也同意@bolov,但如果其他人搜索此警告,那么这可能是唯一的解决方案。【参考方案2】:改用这个:
std::vector<float> DoubleVectorToFloat(const std::vector<double>& x)
std::vector<float> r;
r.reserve(x.size());
std::transform(x.begin(), x.end(), std::back_inserter(r),
[](double a) return static_cast<float>(a); );
return r;
std::transform
是将一种类型的向量转换为另一种类型的向量的正确方法。
我强烈建议这种方法,而不是使用向量构造函数并消除警告。
【讨论】:
我希望有人会发布一个禁用警告的答案,而不是避免它。如果没有,我会接受这个答案。 @TysonHilmer 你有验证你的原始方法和这个之间的性能差异吗? @Caleth。对于这个特定的功能没有。但是我上次分析reserve() 后跟copy( , , back_inserter()) 时,它明显比insert() 慢。所以我不愿意使用它。我只想要简单的隐式转换,没有额外代码的复杂性,并且不要被微软和 SO 上的乐于助人的人告知不要这样做。我知道我在做什么。以上是关于如何为 std::vector 复制或使用隐式缩小转换禁用 Visual Studio 警告 C4244的主要内容,如果未能解决你的问题,请参考以下文章
std::vector emplace_back 可以从向量本身的元素复制构造吗?