繁体   English   中英

如何在 std::vector::emplace_back 上检测隐式转换损失 integer 精度

[英]How to detect implicit conversion losses integer precision on std::vector::emplace_back

我使用-Wconversion编译器选项编译了以下代码,以检测隐式转换丢失 integer 精度:

#include <vector>
#include <cstdint>

int main() {
    std::vector<std::uint16_t> v;
    std::uint32_t a = 0;
    v.emplace_back(a);  // no warning
    v.push_back(a);     // warning: implicit conversion loses integer precision
}

编译演示https://wandbox.org/permlink/K5E4sUlfGBw6C5w8

向量的value_typestd::uint16_t 如果我将std::uint32_tpush_back到向量,那么我会得到以下警告,如我所料。

prog.cc:8:17: warning: implicit conversion loses integer precision: 'std::uint32_t' (aka 'unsigned int') to 'std::__1::vector<unsigned short, std::__1::allocator<unsigned short> >::value_type' (aka 'unsigned short') [-Wimplicit-int-conversion]
v.push_back(a);     // warning: implicit conversion loses integer precision
  ~~~~~~~~~ ^
1 warning generated.

但是,如果我emplace_back与向量相同的值,则不会检测到警告。

我已经测试过它 clang++ 10.0.0、clang++ 9.0.0 和 g++ 9.3.0 并得到了相同的结果。

有什么好方法可以检测 std::vector::emplace_back 上的隐式转换损失 integer 精度吗?

调用v.emplace_back(a)时没有隐式转换。 如果您调用v.emplace_back<const std::uint16_t &>(a)将会有一个隐式转换。

push_backemplace_back之间的关键区别在于后者是模板,而前者不是。 如果您没有为emplace_back指定模板参数,编译器会从 function 参数推导出它,这意味着在调用点不需要转换。 emplace_back中,转换发生在系统 header 中,该系统会抑制警告。

所以在你的例子中,

v.emplace_back(a);

被推断为

v.emplace_back<const std::uint32_t &>(a);

其中 function 参数预计为std::uint32_t 完美匹配,系统外无需转换 header。 如果您要在系统标头中启用警告,您最终可能会收到一堆虚假警告

要在代码中进行隐式转换,您需要强制emplace_back期望std::uint16_t ,这可以通过

v.emplace_back<const std::uint16_t &>(a);

这将在调用emplace_back之前将a隐式转换为std::uint16_t ,以与push_back相同的方式触发编译器警告。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM