为什么编译器会警告 setprecision 中的隐式转换?

Why compiler warns about implicit conversion in setprecision?

提问人:Haldun 提问时间:7/28/2012 更新时间:7/28/2012 访问量:1733

问:

当我编译以下代码时,编译器会给我警告:

"Implicit conversion loses integer precision: 'std::streamsize' (aka 'long') to 'int'". 

我对这个警告有点困惑,因为我只是尝试保存精度的当前值,以便稍后将其设置回原始值。

#include <iomanip>
#include <iostream>

int main() {
  std::streamsize prec = std::cout.precision();
  std::cout << std::setprecision(prec);
}

在这种情况下,保存精度值并稍后将其设置回去的正确方法是什么?

C++

评论

1赞 Prashant Kumar 7/28/2012
您使用的是哪种编译器?我没有收到任何警告或错误g++ -O3 -Wall -Wextra -Werror -pedantic
0赞 Linuxios 7/28/2012
什么编译器?我认为在你的实现上是 ,而需要一个带符号的 .std::streamsizesigned longsetprecisionint
0赞 Linuxios 7/28/2012
@Prashant:必须是 clang、Visual Studio、Borland、Intel C 等。
0赞 YePhIcK 7/28/2012
这正是C++1重新引入关键字的原因,用于从表达式中自动推断变量的类型。否则你的代码在我看来是正确的......auto
0赞 Prashant Kumar 7/28/2012
使用相同的编译器标志时,我也不会收到警告或错误,但我的clang++Apple clang version 2.1 (tags/Apple/clang-163.7.1) (based on LLVM 3.0svn)

答:

11赞 GManNickG 7/28/2012 #1

看起来这只是标准规范中的疏忽。

ios_base::precision有两个重载,一个用于获取,另一个用于设置精度:

// returns current precision
streamsize precision() const;

// sets current precision and returns old value
streamsize precision(streamsize prec) const;

所以这段代码不会给你警告:

#include <iostream>

int main() {
  std::streamsize prec = std::cout.precision(); // gets
  std::cout.precision(prec); // sets
}

但是,该函数只是采用一个普通的旧:setprecision()int

unspecified-type setprecision(int n);

并返回一个未指定的函子,当流使用该函子时,该函子具有以下效果:str

str.precision(n);

在您的情况下,不是(也不必是),因此发出警告。标准可能应该改变,使 的参数不是 ,而是 。streamsizeintsetprecisionintstreamsize

你可以像上面一样称呼自己,也可以假设就足够了。precison()int

#include <iomanip>
#include <iostream>

int main() {
  std::streamsize prec = std::cout.precision();
  std::cout << std::setprecision(static_cast<int>(prec));
}

编辑:显然它被提交修复并且没有达到任何共识(作为非缺陷关闭)。