rmc*_*701 2 c++11 c++-chrono visual-studio-2012
我正在将一些C++代码移植到Windows(来自Linux/g ++ 4.8.1),我注意到Microsoft的持续时间模数运算符的实现是不正确的.
简单的程序
#include <chrono>
#include <iostream>
using namespace std::chrono;
int main(void)
{
std::cout << (milliseconds(1050)%seconds(1)).count() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用Microsoft Visual Studio 2012编译时会出现编译错误:
error C2228: left of '.count' must have class/struct/union
Run Code Online (Sandbox Code Playgroud)
标准(http://en.cppreference.com/w/cpp/chrono/duration/operator_arith4)的定义为
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 );
Run Code Online (Sandbox Code Playgroud)
即模数运算符返回公共类型的持续时间.Microsoft的实现(http://msdn.microsoft.com/en-us/library/hh874810.aspx)定义为
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);
Run Code Online (Sandbox Code Playgroud)
这会错误地返回基础持续时间存储类型.这是一个错误,还是我错过了什么?
是的,这是一个错误,修复程序在Visual Studio 2015中可用.
它是一个实现错误的原因来自维度分析.
显然,如果我们seconds从seconds结果中减去seconds.
seconds = seconds - seconds
Run Code Online (Sandbox Code Playgroud)
而如果我们把seconds通过seconds,结果是一个标量(标量没有单位).
scalar = seconds / seconds
Run Code Online (Sandbox Code Playgroud)
最后一个可以乘以seconds标量并得到seconds.
seconds = seconds * scalar
seconds = scalar * seconds
Run Code Online (Sandbox Code Playgroud)
在[expr.mul]/p4中,标准定义了模数运算符:
...如果商
a/b在结果类型中可表示,(a/b)*b + a%b则等于a......
说的略有不同:
a % b = a - (a/b)*b
Run Code Online (Sandbox Code Playgroud)
所以a duration % duration具有相同的单位:
seconds - (seconds/seconds)*seconds
Run Code Online (Sandbox Code Playgroud)
这简化为just seconds,而不是标量.
同样的分析解释了原因:
seconds % scalar = seconds
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
491 次 |
| 最近记录: |