web-dev-qa-db-ja.com

静的constexpr変数vs関数

浮動小数点定数をstatic constexpr変数として宣言することと、以下の例のように関数との間に違いはありますか、それとも単なるスタイルの問題ですか?

class MY_PI
{
public:
    static constexpr float MY_PI_VAR = 3.14f;
    static constexpr float MY_PI_FUN() { return 3.14f; }
}
55
user2052436

constexpr関数

関数には、(C++ 14まで)自由変数にはない利点があります。クラスボイラープレートがなくても簡単にテンプレート化できます。つまり、テンプレート引数に応じてpiを正確に指定できます。

template<typename T>
constexpr T pi();

template<>
constexpr float pi() { return 3.14f; }

template<>
constexpr double pi() { return 3.1415; }

int main()
{
    constexpr float a = pi<float>();
    constexpr double b = pi<double>();
}

ただし、無料の関数の代わりにstaticメンバー関数を使用する場合、staticメンバー変数よりも短くも簡単でもありません。

constexpr変数

変数を使用する主な利点は、それです。定数が欲しいですよね?それは意図を明確にしますそしてそれはここで最も重要なポイントの1つかもしれません。

クラスと同等の動作を維持することもできますが、クラスがその他の数学定数を含むクラスである場合は、次のように使用する必要があります。

constexpr float a = constants<float>::pi;

または、クラスがpiを表すことのみを目的としている場合は、次のようにします。

constexpr double = pi<double>::value;

最初のケースでは、変数を使用する方が好都合な場合があります。これは、書く方が短く、定数を使用して何かを計算しようとしていないことを実際に示すためです。ただし、piを表すクラスしかない場合は、クラス全体ではなく、無料のconstexpr関数を使用できます。私見はもっと簡単でしょう。

C++ 14: constexpr変数テンプレート

ただし、C++ 11の代わりにC++ 14を使用することを選択した場合、次の種類のconstexpr変数テンプレートを作成できることに注意してください。

template<typename T>
constexpr T pi = T(3.1415);

これにより、次のようなコードを記述できます。

constexpr float a = pi<float>;

C++ 14から、これは物事を行うための好ましい方法かもしれません。古いバージョンの標準を使用している場合でも、最初の2つの段落は保持されます。

54
Morwenn