本の虫

著者:江添亮
ブログ: http://cpplover.blogspot.jp/
メール: boostcpp@gmail.com
Twitter: https://twitter.com/EzoeRyou
GitHub: https://github.com/EzoeRyou

アマゾンの江添のほしい物リストを著者に送るとブログ記事のネタになる

筆者にブログのネタになる品物を直接送りたい場合、住所をメールで質問してください。

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