非constexpr文脈内でconstexpr関数をコンパイル時評価したような気分になる方法

どうやら本日学生生活最終日らしいです。不思議

std::cout<<log(42);

このような場合logがconstexpr関数であってもコンパイル時に評価されない
constexpr関数はconstexprな文脈でのみ呼び出されからだ。上記はconstexpr文脈ではない


よってlogをコンパイル時に評価したい場合constexprな文脈で呼び出す必要がある
例えば以下の通りだ

constexpr auto a=log(42);//コンパイル時に処理される
std::cout<<a;

このプログラムは以下と同等に動くことが期待される

std::cout<<3.73767;

しかしこれはだるい。なのでこんなマクロを作ってみた


#define MACRO(expr) ([]{constexpr auto a=(expr);return a;}())

これを使うとconstexpr呼び出ししたような気分になれる。気分?気分

以下のようになるはずだ

std::cout<<MACRO(log(42));

std::cout<<[]{constexpr auto a=log(42);return a;}();
std::cout<<[]{return 3.73767;}();

最後は関数がinline展開されて

std::cout<<3.73767;

となるはずだ。コンパイラの最適化が十分に働いてくれれば


[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ
この場合だとマクロを使わずベタに書いている場合0.75秒かかっているのに対し
マクロ版は0.09秒で計算を終えている


ただし、コンパイラ最適化を強くした場合
[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ
両者ほとんど変わらない数値を出している。人生大体コンパイラがどうにかしてくれる。コンパイラに母性を求める日も近い