2010-01-09

constexpr修飾は、関数の型ではない

constexpr specifierは、関数の型としては認識されない。

constexpr int bar(int x, int y) // OK
{ return x + y + x*y; }
// ...
int bar(int x, int y) // error: barを再定義している。
{ return x * 2 + 3 * y; }

つまり、constexprかどうかで、関数のオーバーロードはできない。

ただし、non-static なメンバ関数にconstexpr specifierを指定した場合、const specifierを指定したのと、同じ効果がある。

class Foo
{
    int value_ ;

public :
    explicit constexpr Foo(int value) : value_(value) {}
    constexpr int get() { return value_ ; }
} ;

constexpr Foo foo(123) ; // OK
int const x = foo.get() ;// OK

これ以外では、関数の型に影響を与えることはない。

また、constexpr specifierの付いた関数は、{ return expression ; }の形でなければならない。つまり、ifとかswitchとか、forとかwhileとか、gotoなんてものは使えない。ただし、三項演算子が使えるし、再帰もできるので、最低限の分岐やループは実装できる。

例えば、以下は階乗の計算をする関数である。ご覧のように、三項演算子と再帰を使って、条件分岐とループを実現出来ている。

constexpr int factorial(int x)
{
    return x == 0 ? 1 :  x * factorial(x - 1) ;
}


int main()
{
    int const x = factorial(5) ; // 120
    int const y = factorial(10) ; // 3628800
}

No comments: