constexpr でエラー出力

例えば、次のような除算を行う関数で、ゼロ除算の場合にエラーを出力したいと思います。

constexpr int
division(int a, int b){
    return a / b;
}

constexpr int x1 = division(4, 2);    // ok
constexpr int x2 = division(4, 0);    // ゼロ除算を行うのでエラー


本当なら関数内で

static_assert(b == 0, "division by zero")

と書きたいのですが、残念ながら関数内で b が constexpr か判断する事は出来ないので static_assert は使用する事が出来ません。
そんな感じでコンパイル時にエラー出力ができないかやってみました。

[ソース]

constexpr int
division(int a, int b){
    struct error_division_by_zero{
        int operator()() const{ throw("division by zero"); }
    };
    return b == 0 ? error_division_by_zero()()
         : a / b;
}

int
main(){
    constexpr int x1 = division(4, 2);    // ok
    constexpr int x2 = division(4, 0);    // error
    // error: call to non-constexpr function 'int division(int, int)::error_division_by_zero::operator()() const'
    return 0;
}

[エラー内容]

main.cpp|24 col 29| in constexpr expansion of 'division(4, 0)'
main.cpp|17 col 43| error: call to non-constexpr function 'int division(int, int)::error_division_by_zero::operator()() const'


とりあえず、gcc で視覚的に分かるようなエラーを出力してみました。
まぁやっていることはソースをエラーを見てもらえれば分かると思います。
constexpr が gcc 以外ではまだ実装されていないので、他のコンパイラではどうなるのかしら。


また、上記の場合では、throw していますが、

int operator()() const{ assert(false); return 0; }

みたいに定義してもいいと思います。


などと考えてみたのですが、下記のサイトを参考にしたほうがいいかも…?

[コンパイラ]

  • g++ (GCC) 4.7.0 20111210 (experimental)