LoginSignup
6
6

More than 5 years have passed since last update.

constexprラムダ式で包んだconstexpr変数をconstexprではない関数に渡すお話

Last updated at Posted at 2018-04-06

g++7.2.0とclang5.0.0で確認してたはず。

方法

constexprではない通常の関数にconstexpr変数を渡すことはできません。

// これはもちろんコンパイルエラー

void func(char const* x)
{
    constexpr auto y = x;
}

int main()
{
    constexpr auto x = "abc";
    func( x );
}

そこで、C++17で追加されたconstexprラムダ式を使います。constexprラムダ式でconstexpr変数を包むことで、通常の関数でもconstexpr変数を渡すことができるようになります。

// これは通る

template <typename F>
void func(F f)
{
    constexpr auto y = f();
}

int main()
{
    // 明示的にconstexprラムダ式を書いた場合
    func( []() constexpr { return "abc"; } );

    // constexprラムダ式でもキャプチャできるので
    constexpr auto x = "abc";
    func( [&]{ return x; } );
}

条件を満たせばラムダ式のconstexprを暗黙にすることができる(N4659 [expr.prim.lambda.closure]/p4)ので、引数がない場合に()を省略できることを合わせて、以下のように簡単にすることができます。

int main()
{
    func( []{ return "abc"; } );
}

最後に

これを応用することで、printfのフォーマットのコンパイル時チェック等ができたりします。
 
 

・・・やっぱり本当にいいの、これ?

参考

ラムダ式を使って関数の引数からconstexpr変数を定義できたことに関する質問 - スタック・オーバーフロー
https://ja.stackoverflow.com/questions/38123/

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6