Microsoft C ++ 2012中std :: chrono :: duration :: operator%()的不合格返回值 [英] non conforming return value for std::chrono::duration::operator%() in Microsoft C++ 2012
问题描述
我正在将一些C ++代码移植到Windows(从Linux / g ++ 4.8.1),我注意到,微软的持续时间的运算符的实现是不正确的。
简单程序
#include< chrono>
#include< iostream>
使用命名空间std :: chrono;
int main(void)
{
std :: cout< (毫秒(1050)%秒(1))count()< std :: endl;
return 0;
}
当您使用Microsoft Visual Studio 2012编译时出现编译错误:
错误C2228:'.count'的左侧必须有class / struct / union
标准( http ://en.cppreference.com/w/cpp/chrono/duration/operator_arith4 )
的定义为
template<类Rep1,类Period1,类Rep2,类Period2>
typename common_type< duration< Rep1,Period1>,duration< Rep2,Period2>> :: type
constexpr operator%(const duration< Rep1,Period1>& lhs,
const duration< ; Rep2,Period2>& rhs);
模运算符返回公共类型的持续时间。 Microsoft的实施( http://msdn.microsoft.com/en-us/library/ hh874810.aspx )定义为
模板< class Rep1,类Period1,类Rep2,类Period2>
constexpr typename common_type< Rep1,Rep2> :: type
operator%(
const duration< Rep1,Period1>& Left,
const duration< Rep2,Period2&对);
这不正确地返回基本持续时间存储类型。
是的,这是一个错误,修复程序可在Visual Studio 2015 。
这是一个实施错误的原因来自于维度分析。
显然,如果我们从秒减去
秒
,结果是秒
。
秒=秒 - 秒
如果我们用 seconds
除
scalar = seconds / seconds
最后可以用标量乘以秒
,得到秒
。
秒=秒*标量
秒=标量*秒
在[expr.mul] / p4中,标准定义了运算符:
< >
...如果商的
a / b
可以在结果类型中表示,
a / b)* b + a%b
等于a
...
略有不同:
a%b = a - (a / b)* b
因此,
duration%duration
相同单位:秒 - (秒/秒)*秒
pre>
这简化到
秒
,而不是标量。
同样的分析解释了为什么:
秒%scalar =秒
I'm in the process of porting some C++ code to Windows (from Linux/g++4.8.1) and I noticed that Microsoft's implementation of the duration's modulus operator is incorrect.
The simple program
#include <chrono> #include <iostream> using namespace std::chrono; int main(void) { std::cout << (milliseconds(1050)%seconds(1)).count() << std::endl; return 0; }
when compiled with Microsoft Visual Studio 2012 gives the compilation error:
error C2228: left of '.count' must have class/struct/union
The standard (http://en.cppreference.com/w/cpp/chrono/duration/operator_arith4) has the definition as
template< class Rep1, class Period1, class Rep2, class Period2 > typename common_type<duration<Rep1,Period1>, duration<Rep2,Period2>>::type constexpr operator%( const duration<Rep1,Period1>& lhs, const duration<Rep2,Period2>& rhs );
I.e. the modulus operator returns a duration of the common type. Microsoft's implementation (http://msdn.microsoft.com/en-us/library/hh874810.aspx) has the definition as
template<class Rep1, class Period1, class Rep2, class Period2> constexpr typename common_type<Rep1, Rep2>::type operator%( const duration<Rep1, Period1>& Left, const duration<Rep2, Period2>& Right);
This incorrectly returns the underlying duration storage type. Is this a bug, or am I missing something?
解决方案Yes, this is a bug and the fix is available in Visual Studio 2015.
The reason it's an implementation bug comes from dimensional analysis.
Clearly if we subtract
seconds
fromseconds
the result isseconds
.seconds = seconds - seconds
And if we divide
seconds
byseconds
, the result is a scalar (a scalar has no units).scalar = seconds / seconds
And finally one can multiply
seconds
by a scalar and getseconds
.seconds = seconds * scalar seconds = scalar * seconds
In [expr.mul]/p4 the standard defines the modulus operator:
... if the quotient
a/b
is representable in the type of the result,(a/b)*b + a%b
is equal toa
...Said slightly differently:
a % b = a - (a/b)*b
So a
duration % duration
has the same units as:seconds - (seconds/seconds)*seconds
which simplifies down to just
seconds
, and not a scalar.The same analysis explains why:
seconds % scalar = seconds
这篇关于Microsoft C ++ 2012中std :: chrono :: duration :: operator%()的不合格返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!