30

std::ratio<>コンパイル時の有理数演算を可能にする C++11 標準のクラスを見ていました。

constexprテンプレートの設計とクラスで実装された操作が非常に複雑であることに気付きました。非常に単純な有理クラスを実装し、演算子の関数を定義することによって、より直接的で直感的なアプローチを使用できない理由は見つかりませんでした。その結果、クラスが使いやすくなり、コンパイル時の利点が残っていたはずです。

std::ratio<>を使用した単純なクラスの実装と比較して、現在の設計の利点を理解している人はいますconstexprか? 実際、現在の実装に利点を見つけることはできません。

4

4 に答える 4

46

N2661が提案されたとき、提案の作成者は誰もを実装したコンパイラにアクセスできませんでしたconstexpr。そして、私たちの誰も、私たちが構築してテストすることができなかった何かを提案することをいとわなかった。したがって、より良い設計を行うことができたかどうかは、constexpr設計の考慮事項の一部ではありませんでした。設計は、当時の作者が利用できるツールのみに基づいていました。

于 2012-09-07T22:22:00.647 に答える
15

constexpr ソリューションは、まったく異なる問題を解決します。std::ratioは、数学的ツールとしてではなく、異なる単位を使用する変数間のブリッジとして使用するために作成されました。このような状況では、必ず比率を型の一部にする必要があります。constexpr ソリューションはそこでは機能しません。たとえば、std::duration各期間オブジェクトはオブジェクト内で分子/分母の情報を保持する必要があるため、ランタイム スペースとランタイム コストなしで実装することはできません。

于 2012-09-07T23:25:52.087 に答える
1

演算子の constexpr 関数の定義

既存の の上でこれを行うことができますstd::ratio

#include <ratio>

// Variable template so that we have a value
template< 
    std::intmax_t Num, 
    std::intmax_t Denom = 1 
>
auto ratio_ = std::ratio<Num, Denom>{};

// Repeat for all the operators
template< 
    std::intmax_t A, 
    std::intmax_t B,
    std::intmax_t C,
    std::intmax_t D
>
constexpr typename std::ratio_add<std::ratio<A, B>, std::ratio<C, D>>::type
operator+(std::ratio<A, B>, std::ratio<C, D>) {}

// Printing operator
template< 
    std::intmax_t A, 
    std::intmax_t B
>
std::ostream &operator<<(std::ostream &os, std::ratio<A, B> r) {
    return os << decltype(r)::num << "/" << decltype(r)::den;
}
#include <iostream>


int main() {
    std::cout << ratio_<1,2> + ratio_<1,3> << std::endl;
    return 0;
}
5/6
于 2018-06-08T22:06:02.663 に答える
0

std::ratioテンプレートのメタプログラミングと型操作のおかげで、その周囲のメカニズムは常にコンパイル時に実行されます。constexprC++ 機能 (テンプレート パラメーターや変数の初期化など) で定数式が必要な場合にのみ、実行時に実行する必要がありますconstexpr

では、コンパイル時の実行と「より簡単で直感的」であることのどちらが重要ですか?

于 2012-09-07T21:48:59.003 に答える