2

私はいくつかの C++ コードを (Linux/g++4.8.1 から) Windows に移植する過程にあり、期間のモジュラス演算子の Microsoft の実装が正しくないことに気付きました。

簡単なプログラム

#include <chrono>
#include <iostream>

using namespace std::chrono;

int main(void)
{
    std::cout << (milliseconds(1050)%seconds(1)).count() << std::endl;
    return 0;
}

Microsoft Visual Studio 2012 でコンパイルすると、コンパイル エラーが発生します。

error C2228: left of '.count' must have class/struct/union

標準 ( 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 );

つまり、モジュラス演算子は共通型の期間を返します。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);

これは、基になる期間ストレージ タイプを誤って返します。これはバグですか、それとも何か不足していますか?

4

1 に答える 1

8

はい、これはバグであり、修正は Visual Studio 2015 で利用できます

実装のバグである理由は、次元分析に由来します。

明らかに、結果secondsから差し引くと です。secondsseconds

seconds = seconds - seconds

で割るsecondsseconds、結果はスカラーになります (スカラーには単位がありません)。

scalar = seconds / seconds

最後にseconds、スカラーを掛けて を得ることができますseconds

seconds = seconds * scalar
seconds = scalar * seconds

[expr.mul]/p4 では、標準でモジュラス演算子が定義されています。

...商a/bが結果の型で表現 できる場合、 ...(a/b)*b + a%bに等しいa

少し違った言い方をします:

a % b = a - (a/b)*b

したがって、 aduration % durationは次の単位と同じです。

seconds - (seconds/seconds)*seconds

secondsこれは、スカラーではなく、だけに単純化されます。

同じ分析で理由が説明されています。

seconds % scalar = seconds
于 2013-07-21T15:44:35.320 に答える