2014-10-02

C++14の新機能: constexpr関数の制限緩和

C++14では、constexprの制限が大幅に緩和された。

C++11で追加されたconstexpr関数は、コンパイル時定数式として評価できる関数である。

constexpr std::size_t size()
{ return 10 ; }

// OK、size()は定数式
int a[size()] ;

しかし、C++11のconstexpr関数には、極めて厳しい制約がある。constexpr関数の本体は、実質、return文ひとつしか認められていないのだ。

プログラミングというのは、通常、変数や条件分岐やループといった機能を使う。constexpr関数では、それらの機能は実現可能ではあるが、C++としては極めて不自然な方法を用いなければならない。変数は引数に追い出し、条件分岐は条件演算子(?:)を使い、ループには再帰をしなければならない。

たとえば、変数、条件分岐、ループを使いたいsqrtを、C++11のconstexpr関数で書くと、以下のようになる。

// C++11のconstexpr関数によるsqrtの実装
template < typename T >
constexpr T sqrt_aux( T s, T x, T prev )
{
    return x != prev ? 
        sqrt_aux( s, ( x + s / x ) / 2.0, x ) : x ;
}

template < typename T >
constexpr T sqrt( T s )
{ return sqrt_aux( s, s/2.0, s ) ; }

C++14では、constexpr関数の制約が大幅に緩和された。C++14のconstexpr関数では、sqrtは以下のように書くことができる。

template < typename T >
constexpr T sqrt( T s )
{
    T x = s / 2.0 ;
    T prev = 0.0 ;

    while ( x != prev )
    {
        prev = x ;
        x = (x + s / x ) / 2.0 ;
    }
    return x ;
}

C++14のconstexpr関数は、変数の宣言ができる。ただし、必ず初期化されなければならず、staticとthread_local変数は宣言できない。


constexpr int f( int x )
{
    int l = x ; // OK

    int e1 ; // エラー、未初期化
    static int e2 ; // エラー
    thread_local int e3 ; // エラー

    return 0 ; 
}

変数を変更することもできる。変更できる変数は、定数式の評価とともに寿命が始まったものだけだ。

constexpr int f( int x )
{
    int l = x ;
    l += 1 ;
    ++l ;
    --l ;

    return l ;
}

条件分岐として、if文とswitch文を使うことができる。goto文は使えない。

ループとして、for, while, do whileを使うことができる。

まとめとして、一言で言えば、C++14のconstexpr関数は、普通に書けるようになったということだ。

なおこの機能はClang 3.4で実装されている。GCCではまだ実装されていない。

Clang - C++1z, C++14, C++11 and C++98 Status

C++1y/C++14 Support in GCC - GNU Project - Free Software Foundation (FSF)

See Also:

本の虫: C++14の新機能: 2進数リテラル

本の虫: C++14の新機能: decltype(auto)

本の虫: C++14の新機能: 関数の戻り値の型推定

本の虫: C++14の新機能: 初期化lambdaキャプチャー

本の虫: C++14の新機能: 変数テンプレート

ドワンゴ広告

この記事はドワンゴ勤務中に書かれた。

そういえば、最近、社内で昼ボドゲをしていない。金曜の夜は大抵ボドゲが行われているが。

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

1 comment:

Anonymous said...

あぁ、constexpr!VCが夢見る機能デス。