SlideShare a Scribd company logo
1 of 59
Download to read offline
Effective Modern C++
勉強会#3
Item 15
刈谷 満(@kariya_mitsuru)
2015/3/25
Item 15: Use constexpr whenever possible.
「市民、あなたは constexpr ですか」
「もちろんです、C++。constexpr で
あることは市民の義務です」
© ボレロ村上
Item 15: Use constexpr whenever possible.
constexpr - 混乱しやすい新語オブザC++11
最高金賞受賞!!!
const に毛の生えたようなの、と思っていませんか?
オブジェクトに使えばだいたい合ってる。
⇓
単なる定数じゃなくてコンパイル時に分かる定数
Item 15: Use constexpr whenever possible.
constexpr - 混乱しやすい新語オブザC++11
最高金賞受賞!!!
const に毛の生えたようなの、と思っていませんか?
でも関数に使うと…
⇓
関数の結果が定数なわけでもましてやコンパイル時定数とも限らない。
Item 15: Use constexpr whenever possible.
でもまずは、
constexpr オブジェクトから。
Item 15: Use constexpr whenever possible.
constexpr オブジェクトとは
1. const オブジェクト
2. だけじゃない!
コンパイル時に値が分かるオブジェクト!
ホントはコンパイル時じゃなくて
リンク時でいい時もあるんだけど…
Item 15: Use constexpr whenever possible.
constexpr オブジェクトの特徴
• ROMに置ける。
⇒特に組み込みシステムでは重要な機能
• "integral constant expression" が要求される箇所で使用する
ことができる。
⇒例えば、配列サイズ、整数テンプレート実引数(std::array
の長さとか)、列挙子の値、アラインメント指定、などなど。
Item 15: Use constexpr whenever possible.
int sz;
…
constexpr auto arraySize1 = sz;
std::array<int, sz> data1;
constexpr auto arraySize2 = 10;
std::array<int, arraySize2> data2;
エラー!
sz の値は
コンパイル時には分からない
OK!
10 はコンパイル時定数
OK!
arraySize2 は constexpr
非 constexpr 変数
Item 15: Use constexpr whenever possible.
一応注意しておくと、
単なる const じゃダメだよ。
Item 15: Use constexpr whenever possible.
int sz;
…
const auto arraySize = sz;
std::array<int, arraySize> data;
非 constexpr 変数(前と一緒)
OK!
arraySize は
sz の const コピー
エラー!
arraySize の値は
コンパイル時には分からない
Item 15: Use constexpr whenever possible.
簡単にいえば、
constexpr オブジェクトは const だけど、
逆は必ずしも真では無い。
もしコンパイル時定数が欲しければ、
const じゃなくて constexpr を使う事。
Item 15: Use constexpr whenever possible.
簡単にいえば、
constexpr オブジェクトは const だけど、
逆は必ずしも真では無い。
もしコンパイル時定数が欲しければ、
const じゃなくて constexpr を使う事。
(余談)あれ?
今まで const 変数で配列の
サイズとかテンプレート引数とか
指定してきたような~?
だけどOK!でも何で?だからOK!
Item 15: Use constexpr whenever possible.
const int arraySize = 10;
std::array<int, arraySize> data;
constexpr 変数じゃないconstexpr 変数じゃない
けどコンパイル時定数!
Item 15: Use constexpr whenever possible.
簡単にいえば、
constexpr オブジェクトは const だけど、
逆は必ずしも真では無い。
もしコンパイル時定数が欲しければであることを保証したければ、
const じゃなくて constexpr を使う事。
Item 15: Use constexpr whenever possible.
(余談)ちなみに…
constexpr なオブジェクトは初期化無しでは宣言できません!
constexpr int var; エラー!
初期化子がない!
Item 15: Use constexpr whenever possible.
(余談)ちなみに…
constexpr な静的オブジェクトは普通の const なオブジェクトと一
緒でデフォルト内部リンケージ!
だから、ヘッダで定義しておくと実体がいっぱいできたりする。
(事がある。ODR-used の関係で実体が出来ないことも多いけど…)
だからと言って、ヘッダファイルで extern 指定して外部リンケージ
にすると、リンク時にぶつかる…
Item 15: Use constexpr whenever possible.
さてお待ちかね、constexpr な関数です。
constexpr 関数に、コンパイル時定数だけを与えると…
⇒コンパイル時定数!
コンパイル時定数が必要な所で使える!
constexpr 関数に、コンパイル時定数以外も与えると…
⇒普通(コンパイル時定数ではない)
コンパイル時定数が必要な所で使うとエラー!
Item 15: Use constexpr whenever possible.
さてお待ちかね、constexpr な関数です。
constexpr 関数に、コンパイル時定数だけを与えると…
⇒コンパイル時定数!
コンパイル時定数が必要な所で使える!
constexpr 関数に、コンパイル時定数以外も与えると…
⇒普通(コンパイル時定数ではない)
コンパイル時定数が必要な所で使うとエラー!
(余談)
…実はそうとも限らないんだけど…
Item 15: Use constexpr whenever possible.
(余談)引数がコンパイル時定数でもダメな例
constexpr int div(int numer, int denom) {
return numer / denom;
}
constexpr int i1 = div(1, 0);
constexpr int lshift(int num, int bit) {
return num << bit;
}
constexpr int i2 = lshift(1, -1);
エラー!
0 除算はUB!
エラー!
マイナスシフトはUB!
Item 15: Use constexpr whenever possible.
例えば…
様々な条件下での実験結果をstd::arrayに格納したい!
かつ
条件の種類はn種類あって、それぞれ3通りの状態がある!
⇓
std::pow(3, n) でおk?
Item 15: Use constexpr whenever possible.
例えば…
様々な条件下での実験結果をstd::arrayに格納したい!
かつ
条件の種類はn種類あって、それぞれ3通りの状態がある!
⇓
std::pow(3, n) でおk?
Item 15: Use constexpr whenever possible.
ダメな理由
その1:std::pow は浮動小数点型!
⇒std::size_t にキャストすればいんじゃね?
その2:std::pow は constexpr じゃない!
⇒つらぽよ…
Item 15: Use constexpr whenever possible.
ダメな理由
その1:std::pow は浮動小数点型!
⇒std::size_t にキャストすればいんじゃね?
その2:std::pow は constexpr じゃない!
⇒つらぽよ…
じゃあ
sprout::pow 使おう!!!
じゃあ
sprout::pow 使おう!!!
作ろう!!!
pow は constexpr 関数
Item 15: Use constexpr whenever possible.
constexpr
int pow(int base, int exp) noexcept
{
…
}
こんなの作れば、std::array のサイズ指定も怖くない!
constexpr auto numConds = 5;
std::array<int, pow(3, numConds)> results;
pow は constexpr 関数
ちなみに例外も吐かないよ
実装は後のお楽しみだ。
クックックッ…
results の要素数は
3 の numConds 乗!
Item 15: Use constexpr whenever possible.
しかも、これなら実行時にもお使い頂けます!
auto base = readFromDB(“base”);
auto exp = readFromDB(“exponent”);
auto baseToExp = pow(base, exp);
値を実行時に取得すると…
pow 関数も
実行時に呼び出し!
Item 15: Use constexpr whenever possible.
しかも、これなら実行時にもお使い頂けます!
auto base = readFromDB(“base”);
auto exp = readFromDB(“exponent”);
auto baseToExp = pow(base, exp);
値を実行時に取得すると…
pow 関数も
実行時に呼び出し!
T
M
P
と
は
違
う
の
だ
よ
、
T
M
P
と
は
© ランバ・ラル
Item 15: Use constexpr whenever possible.
で、どうやって書くの?
C++11 だと…
関数本体に書ける実行文は return 文 1 つだけ!
え~と…でも、まあ、
if 文使えなくても条件演算子 ?: があるし、
ループ書けなくても再帰があるし、
return 文 1 つだけでも関係ないよね!
Item 15: Use constexpr whenever possible.
constexpr int pow(int base, int exp) noexcept
{
return (exp == 0 ? 1 : base * pow(base, exp - 1));
}
このくらいだったら、まぁ何とか読み書きできるけど、
ちょっと複雑になったら辛いなぁ…
Item 15: Use constexpr whenever possible.
ちなみに、C++14 なら…
constexpr int pow(int base, int exp) noexcept // C++14
{
auto result = 1;
for (int i = 0; i < exp; ++i)
result *= base;
return result;
}
見える、見えるぞ…
私にも、コードが見える!
Item 15: Use constexpr whenever possible.
実はいろいろ制約あり
引数と戻り値の型は「リテラル型」じゃないとダメなんです。
リテラル型って何ぞ?
平たく言うと、コンパイル時定数になれる型のこと。
Item 15: Use constexpr whenever possible.
リテラル型
C++11 では、組み込み型は void を除いて全部OK!
ユーザ定義型も一定の条件を満たせばOK!
だってコンストラクタやメンバ関数も constexpr になれるから!
Item 15: Use constexpr whenever possible.
リテラル型
C++11 では、組み込み型は void を除いて全部OK!
ユーザ定義型も一定の条件を満たせばOK!
だってコンストラクタやメンバ関数も constexpr になれるから!
…どゆこと?
class Point {
public:
constexpr Point(double xVal = 0, double yVal = 0) noexcept
: x(xVal), y(yVal) {}
constexpr double xValue() const noexcept { return x; }
constexpr double yValue() const noexcept { return y; }
void setX(double newX) noexcept { x = newX; }
void setY(double newY) noexcept { y = newY; }
private:
double x, y;
};
Item 15: Use constexpr whenever possible.
class Point {
public:
constexpr Point(double xVal = 0, double yVal = 0) noexcept
: x(xVal), y(yVal) {}
constexpr double xValue() const noexcept { return x; }
constexpr double yValue() const noexcept { return y; }
void setX(double newX) noexcept { x = newX; }
void setY(double newY) noexcept { y = newY; }
private:
double x, y;
};
Item 15: Use constexpr whenever possible.
constexpr コンストラクタに
コンパイル時定数を渡すと…
全てのメンバ変数が
コンパイル時定数になる!
class Point {
public:
constexpr Point(double xVal = 0, double yVal = 0) noexcept
: x(xVal), y(yVal) {}
constexpr double xValue() const noexcept { return x; }
constexpr double yValue() const noexcept { return y; }
void setX(double newX) noexcept { x = newX; }
void setY(double newY) noexcept { y = newY; }
private:
double x, y;
};
Item 15: Use constexpr whenever possible.
constexpr コンストラクタに
コンパイル時定数を渡すと…
全てのメンバ変数が
コンパイル時定数になる!
オブジェクト自体も
コンパイル時定数に
なる!
Item 15: Use constexpr whenever possible.
constexpr Point p1(9.4, 27.7);
constexpr Point p2(28.8, 5.3);
constexpr
Point midpoint(const Point& p1, const Point& p2) noexcept
{
return { (p1.xValue() + p2.xValue()) / 2,
(p1.yValue() + p2.yValue()) / 2 };
}
constexpr auto mid = midpoint(p1, p2);
constexpr オブジェクトを
constexpr 関数の結果で初期化!
コンパイル時定数!!!
constexpr
メンバ関数を呼ぶ!
constexpr コンストラクタは
コンパイル時に走る!
コンパイル時定数!!!
Item 15: Use constexpr whenever possible.
constexpr Point p1(9.4, 27.7);
constexpr Point p2(28.8, 5.3);
constexpr
Point midpoint(const Point& p1, const Point& p2) noexcept
{
return { (p1.xValue() + p2.xValue()) / 2,
(p1.yValue() + p2.yValue()) / 2 };
}
constexpr auto mid = midpoint(p1, p2);
constexpr オブジェクトを
constexpr 関数の結果で初期化!
コンパイル時定数!!!
constexpr
メンバ関数を呼ぶ!
constexpr コンストラクタは
コンパイル時に走る!
コンパイル時定数!!!
素晴らしい!
Item 15: Use constexpr whenever possible.
今まで
コンパイル時 ------ 超えられない壁 ------ 実行時
今
境界は曖昧に…
Item 15: Use constexpr whenever possible.
今まで
コンパイル時 ------ 超えられない壁 ------ 実行時
今
境界は曖昧に…
実行時処理をコンパイル時処理に
マイグレーションすれば、
実行速度はより速くなる!!!
Item 15: Use constexpr whenever possible.
今まで
コンパイル時 ------ 超えられない壁 ------ 実行時
今
境界は曖昧に…
実行時処理をコンパイル時処理に
マイグレーションすれば、
実行速度はより速くなる!!!
でもコンパイル時間は長く…
Item 15: Use constexpr whenever possible.
今まで
コンパイル時 ------ 超えられない壁 ------ 実行時
今
境界は曖昧に…
実行時処理をコンパイル時処理に
マイグレーションすれば、
実行速度はより速くなる!!!
でもコンパイル時間は長く…
Item 15: Use constexpr whenever possible.
今まで
コンパイル時 ------ 超えられない壁 ------ 実行時
今
境界は曖昧に…
実行時処理をコンパイル時処理に
マイグレーションすれば、
実行速度はより速くなる!!!
でもコンパイル時間は長く…
Item 15: Use constexpr whenever possible.
(余談)ちなみに…
constexpr コンストラクタの使い道は
それだけじゃない!
静的オブジェクトの初期化順の問題の一部を解決できる!
(@cpp_akira さんありがとう!!!)
詳しくは Webで!
http://cpprefjp.github.io/reference/mutex/mutex/op_constructor.html
(後でちょっとだけ出てくるよ!)
Item 15: Use constexpr whenever possible.
ところで…
setX と setY は constexpr じゃないけど、
オブジェクトの値変更するんだから仕方ないよね…
Item 15: Use constexpr whenever possible.
そんなメンバ関数も、constexpr になれる。
そう、
C++14 ならね。
Item 15: Use constexpr whenever possible.
class Point {
public:
…
constexpr void setX(double newX) noexcept // C++14
{ x = newX; }
constexpr void setY(double newY) noexcept // C++14
{ y = newY; }
…
};
Item 15: Use constexpr whenever possible.
C++11 で constexpr に出来なかった理由は…
その1:constexpr メンバ関数は暗黙で const 修飾!
だから、オブジェクトの状態は変更できない!
⇒C++14 からは暗黙の const 修飾は亡くなりました!
その2:戻り値の型 void はリテラル型じゃない!
⇒C++14では void もめでたくリテラル型になりました
Item 15: Use constexpr whenever possible.
(余談)Caution!
constexpr メンバ関数の暗黙 const 修飾は C++14 で亡くなるので、
たとえ C++11 で書いていても constexpr メンバ関数には明示的に
const 修飾しておきましょう!!!
そうしないと、コンパイラが C++14 に移行した時に挙動が変わってしまい
ます!!!
(clang は 3.3 から警告が出ます)
Item 15: Use constexpr whenever possible.
(余談)ちなみに…
constexpr な関数は暗黙で inline です!
(実際、極限のインライン化ですよね…)
だから、普通ヘッダで定義しておく。
(inline だから重複定義にならない)
あと、constexpr として使うには宣言だけじゃなく定義が必要!
Item 15: Use constexpr whenever possible.
でも…
セッタ関数 constexpr で何が嬉しいの?
Item 15: Use constexpr whenever possible.
こんな関数も書けるよ!
// 点 p の原点に対する鏡映を返す(C++14)
constexpr Point reflection(const Point& p) noexcept
{
Point result;
result.setX(-p.xValue());
result.setY(-p.yValue());
return result;
}
非 const の Point を作る
x と y を設定する
それのコピーを返す
Item 15: Use constexpr whenever possible.
当然こんなこともできるよ!
constexpr Point p1(9.4, 27.7);
constexpr Point p2(28.8, 5.3);
constexpr auto mid = midpoint(p1, p2);
constexpr auto reflectedMid =
reflection(mid);
reflectedMid の値は
(-19.1, -16.5) で、
コンパイル時に分かる
このへんは前と一緒
Item 15: Use constexpr whenever possible.
さて、本項目のアドバイスの理由は明らかになったでしょ?
1. constexpr オブジェクトと constexpr 関数は、非 constexpr
のものよりもより多くの文脈で使える。
2. constexpr を使う事で、あなたが作ったオブジェクトや関数の
使用可能なシチュエーションを最大化することができる。
Item 15: Use constexpr whenever possible.
Caution!!!
constexpr はオブジェクトや関数の
インタフェースの一部
だ!
constexpr、それは
"定数式が必要な箇所で使う事が出来る"
という宣言
Item 15: Use constexpr whenever possible.
Caution!!!
constexpr なオブジェクトや関数を提供
⇓
クライアントコード内の定数式が必要な箇所で使われる
⇓
その後、constexpr を削除
⇓
クライアントコードのコンパイルエラーが大量発生!!!
Item 15: Use constexpr whenever possible.
Caution!!!
デバッグやチューニングのために I/O を追加しよ
⇓
一般的に I/O は constexpr 関数内では許されていない
⇓
constexpr 取らなきゃ!!!
Item 15: Use constexpr whenever possible.
Caution!!!
"whenever possible" は、
長期スパンで考えること!
Item 15: Use constexpr whenever possible.
覚えておくこと
• constexpr オブジェクトは、const で、コンパイル中に分かる値で
初期化される。
• constexpr 関数は、コンパイル時に分かる値を引数に呼び出すと、
コンパイル時に結果を生成する。
• constexpr オブジェクトと関数は、非 constexpr オブジェクトと
関数よりも、より幅広い文脈で使用することができる。
• constexpr はオブジェクトと関数のインタフェースの一部である。
Item 15: Use constexpr whenever possible.
さあ、
今日からあなたも
constexpr で
コンパイル時レイトレ!!!

More Related Content

What's hot

Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニック
Genya Murakami
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
kiki utagawa
 

What's hot (20)

クソザコ鳥頭が非順序連想コンテナに入門してみた
クソザコ鳥頭が非順序連想コンテナに入門してみたクソザコ鳥頭が非順序連想コンテナに入門してみた
クソザコ鳥頭が非順序連想コンテナに入門してみた
 
【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things
 
templateとautoの型推論
templateとautoの型推論templateとautoの型推論
templateとautoの型推論
 
Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニック
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
 
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
 
Effective Modern C++ Item 9 and 10
Effective Modern C++ Item 9 and 10Effective Modern C++ Item 9 and 10
Effective Modern C++ Item 9 and 10
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 
effective modern c++ chapeter36
effective modern c++ chapeter36effective modern c++ chapeter36
effective modern c++ chapeter36
 
Pythonと型チェッカー
Pythonと型チェッカーPythonと型チェッカー
Pythonと型チェッカー
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
こわくない Git
こわくない Gitこわくない Git
こわくない Git
 
zshでコマンドライン履歴を活用する
zshでコマンドライン履歴を活用するzshでコマンドライン履歴を活用する
zshでコマンドライン履歴を活用する
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
 

Viewers also liked

Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26
Akihiro Nishimura
 

Viewers also liked (17)

emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
 
Effective modern C++ 勉強会 #3 Item 12
Effective modern C++ 勉強会 #3 Item 12Effective modern C++ 勉強会 #3 Item 12
Effective modern C++ 勉強会 #3 Item 12
 
Effective modern-c++#9
Effective modern-c++#9Effective modern-c++#9
Effective modern-c++#9
 
Effective Modern C++ study group Item39
Effective Modern C++ study group Item39Effective Modern C++ study group Item39
Effective Modern C++ study group Item39
 
Effective Modern C++ 勉強会#7 Item 27
Effective Modern C++ 勉強会#7 Item 27Effective Modern C++ 勉強会#7 Item 27
Effective Modern C++ 勉強会#7 Item 27
 
Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26
 
Effective Modern C++勉強会#2 Item 11(,12)
Effective Modern C++勉強会#2 Item 11(,12)Effective Modern C++勉強会#2 Item 11(,12)
Effective Modern C++勉強会#2 Item 11(,12)
 
Effective Modern C++ 勉強会#6 Item25
Effective Modern C++ 勉強会#6 Item25Effective Modern C++ 勉強会#6 Item25
Effective Modern C++ 勉強会#6 Item25
 
Effective Modern C++ 勉強会#8 Item38
Effective Modern C++ 勉強会#8 Item38Effective Modern C++ 勉強会#8 Item38
Effective Modern C++ 勉強会#8 Item38
 
Effective Modern C++ Item 24: Distinguish universal references from rvalue re...
Effective Modern C++ Item 24: Distinguish universal references from rvalue re...Effective Modern C++ Item 24: Distinguish universal references from rvalue re...
Effective Modern C++ Item 24: Distinguish universal references from rvalue re...
 
Emcjp item33,34
Emcjp item33,34Emcjp item33,34
Emcjp item33,34
 
emcjp Item 42
emcjp Item 42emcjp Item 42
emcjp Item 42
 
Emcjp item21
Emcjp item21Emcjp item21
Emcjp item21
 
Emcpp item31
Emcpp item31Emcpp item31
Emcpp item31
 
Emcpp item41
Emcpp item41Emcpp item41
Emcpp item41
 
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35
 
Effective modern c++ 5
Effective modern c++ 5Effective modern c++ 5
Effective modern c++ 5
 

Similar to Effective Modern C++ 勉強会#3 Item 15

冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
Kumazaki Hiroki
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
Genya Murakami
 

Similar to Effective Modern C++ 勉強会#3 Item 15 (8)

中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
 
C++ マルチスレッド 入門
C++ マルチスレッド 入門C++ マルチスレッド 入門
C++ マルチスレッド 入門
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
すごいConstたのしく使おう!
すごいConstたのしく使おう!すごいConstたのしく使おう!
すごいConstたのしく使おう!
 
VBCPP - ICT+R 2012
VBCPP - ICT+R 2012VBCPP - ICT+R 2012
VBCPP - ICT+R 2012
 

Recently uploaded

Recently uploaded (11)

NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 

Effective Modern C++ 勉強会#3 Item 15

  • 1. Effective Modern C++ 勉強会#3 Item 15 刈谷 満(@kariya_mitsuru) 2015/3/25
  • 2. Item 15: Use constexpr whenever possible. 「市民、あなたは constexpr ですか」 「もちろんです、C++。constexpr で あることは市民の義務です」 © ボレロ村上
  • 3. Item 15: Use constexpr whenever possible. constexpr - 混乱しやすい新語オブザC++11 最高金賞受賞!!! const に毛の生えたようなの、と思っていませんか? オブジェクトに使えばだいたい合ってる。 ⇓ 単なる定数じゃなくてコンパイル時に分かる定数
  • 4. Item 15: Use constexpr whenever possible. constexpr - 混乱しやすい新語オブザC++11 最高金賞受賞!!! const に毛の生えたようなの、と思っていませんか? でも関数に使うと… ⇓ 関数の結果が定数なわけでもましてやコンパイル時定数とも限らない。
  • 5. Item 15: Use constexpr whenever possible. でもまずは、 constexpr オブジェクトから。
  • 6. Item 15: Use constexpr whenever possible. constexpr オブジェクトとは 1. const オブジェクト 2. だけじゃない! コンパイル時に値が分かるオブジェクト! ホントはコンパイル時じゃなくて リンク時でいい時もあるんだけど…
  • 7. Item 15: Use constexpr whenever possible. constexpr オブジェクトの特徴 • ROMに置ける。 ⇒特に組み込みシステムでは重要な機能 • "integral constant expression" が要求される箇所で使用する ことができる。 ⇒例えば、配列サイズ、整数テンプレート実引数(std::array の長さとか)、列挙子の値、アラインメント指定、などなど。
  • 8. Item 15: Use constexpr whenever possible. int sz; … constexpr auto arraySize1 = sz; std::array<int, sz> data1; constexpr auto arraySize2 = 10; std::array<int, arraySize2> data2; エラー! sz の値は コンパイル時には分からない OK! 10 はコンパイル時定数 OK! arraySize2 は constexpr 非 constexpr 変数
  • 9. Item 15: Use constexpr whenever possible. 一応注意しておくと、 単なる const じゃダメだよ。
  • 10. Item 15: Use constexpr whenever possible. int sz; … const auto arraySize = sz; std::array<int, arraySize> data; 非 constexpr 変数(前と一緒) OK! arraySize は sz の const コピー エラー! arraySize の値は コンパイル時には分からない
  • 11. Item 15: Use constexpr whenever possible. 簡単にいえば、 constexpr オブジェクトは const だけど、 逆は必ずしも真では無い。 もしコンパイル時定数が欲しければ、 const じゃなくて constexpr を使う事。
  • 12. Item 15: Use constexpr whenever possible. 簡単にいえば、 constexpr オブジェクトは const だけど、 逆は必ずしも真では無い。 もしコンパイル時定数が欲しければ、 const じゃなくて constexpr を使う事。 (余談)あれ? 今まで const 変数で配列の サイズとかテンプレート引数とか 指定してきたような~?
  • 13. だけどOK!でも何で?だからOK! Item 15: Use constexpr whenever possible. const int arraySize = 10; std::array<int, arraySize> data; constexpr 変数じゃないconstexpr 変数じゃない けどコンパイル時定数!
  • 14. Item 15: Use constexpr whenever possible. 簡単にいえば、 constexpr オブジェクトは const だけど、 逆は必ずしも真では無い。 もしコンパイル時定数が欲しければであることを保証したければ、 const じゃなくて constexpr を使う事。
  • 15. Item 15: Use constexpr whenever possible. (余談)ちなみに… constexpr なオブジェクトは初期化無しでは宣言できません! constexpr int var; エラー! 初期化子がない!
  • 16. Item 15: Use constexpr whenever possible. (余談)ちなみに… constexpr な静的オブジェクトは普通の const なオブジェクトと一 緒でデフォルト内部リンケージ! だから、ヘッダで定義しておくと実体がいっぱいできたりする。 (事がある。ODR-used の関係で実体が出来ないことも多いけど…) だからと言って、ヘッダファイルで extern 指定して外部リンケージ にすると、リンク時にぶつかる…
  • 17. Item 15: Use constexpr whenever possible. さてお待ちかね、constexpr な関数です。 constexpr 関数に、コンパイル時定数だけを与えると… ⇒コンパイル時定数! コンパイル時定数が必要な所で使える! constexpr 関数に、コンパイル時定数以外も与えると… ⇒普通(コンパイル時定数ではない) コンパイル時定数が必要な所で使うとエラー!
  • 18. Item 15: Use constexpr whenever possible. さてお待ちかね、constexpr な関数です。 constexpr 関数に、コンパイル時定数だけを与えると… ⇒コンパイル時定数! コンパイル時定数が必要な所で使える! constexpr 関数に、コンパイル時定数以外も与えると… ⇒普通(コンパイル時定数ではない) コンパイル時定数が必要な所で使うとエラー! (余談) …実はそうとも限らないんだけど…
  • 19. Item 15: Use constexpr whenever possible. (余談)引数がコンパイル時定数でもダメな例 constexpr int div(int numer, int denom) { return numer / denom; } constexpr int i1 = div(1, 0); constexpr int lshift(int num, int bit) { return num << bit; } constexpr int i2 = lshift(1, -1); エラー! 0 除算はUB! エラー! マイナスシフトはUB!
  • 20. Item 15: Use constexpr whenever possible. 例えば… 様々な条件下での実験結果をstd::arrayに格納したい! かつ 条件の種類はn種類あって、それぞれ3通りの状態がある! ⇓ std::pow(3, n) でおk?
  • 21. Item 15: Use constexpr whenever possible. 例えば… 様々な条件下での実験結果をstd::arrayに格納したい! かつ 条件の種類はn種類あって、それぞれ3通りの状態がある! ⇓ std::pow(3, n) でおk?
  • 22. Item 15: Use constexpr whenever possible. ダメな理由 その1:std::pow は浮動小数点型! ⇒std::size_t にキャストすればいんじゃね? その2:std::pow は constexpr じゃない! ⇒つらぽよ…
  • 23. Item 15: Use constexpr whenever possible. ダメな理由 その1:std::pow は浮動小数点型! ⇒std::size_t にキャストすればいんじゃね? その2:std::pow は constexpr じゃない! ⇒つらぽよ… じゃあ sprout::pow 使おう!!! じゃあ sprout::pow 使おう!!! 作ろう!!!
  • 24. pow は constexpr 関数 Item 15: Use constexpr whenever possible. constexpr int pow(int base, int exp) noexcept { … } こんなの作れば、std::array のサイズ指定も怖くない! constexpr auto numConds = 5; std::array<int, pow(3, numConds)> results; pow は constexpr 関数 ちなみに例外も吐かないよ 実装は後のお楽しみだ。 クックックッ… results の要素数は 3 の numConds 乗!
  • 25. Item 15: Use constexpr whenever possible. しかも、これなら実行時にもお使い頂けます! auto base = readFromDB(“base”); auto exp = readFromDB(“exponent”); auto baseToExp = pow(base, exp); 値を実行時に取得すると… pow 関数も 実行時に呼び出し!
  • 26. Item 15: Use constexpr whenever possible. しかも、これなら実行時にもお使い頂けます! auto base = readFromDB(“base”); auto exp = readFromDB(“exponent”); auto baseToExp = pow(base, exp); 値を実行時に取得すると… pow 関数も 実行時に呼び出し! T M P と は 違 う の だ よ 、 T M P と は © ランバ・ラル
  • 27. Item 15: Use constexpr whenever possible. で、どうやって書くの? C++11 だと… 関数本体に書ける実行文は return 文 1 つだけ! え~と…でも、まあ、 if 文使えなくても条件演算子 ?: があるし、 ループ書けなくても再帰があるし、 return 文 1 つだけでも関係ないよね!
  • 28. Item 15: Use constexpr whenever possible. constexpr int pow(int base, int exp) noexcept { return (exp == 0 ? 1 : base * pow(base, exp - 1)); } このくらいだったら、まぁ何とか読み書きできるけど、 ちょっと複雑になったら辛いなぁ…
  • 29. Item 15: Use constexpr whenever possible. ちなみに、C++14 なら… constexpr int pow(int base, int exp) noexcept // C++14 { auto result = 1; for (int i = 0; i < exp; ++i) result *= base; return result; } 見える、見えるぞ… 私にも、コードが見える!
  • 30. Item 15: Use constexpr whenever possible. 実はいろいろ制約あり 引数と戻り値の型は「リテラル型」じゃないとダメなんです。 リテラル型って何ぞ? 平たく言うと、コンパイル時定数になれる型のこと。
  • 31. Item 15: Use constexpr whenever possible. リテラル型 C++11 では、組み込み型は void を除いて全部OK! ユーザ定義型も一定の条件を満たせばOK! だってコンストラクタやメンバ関数も constexpr になれるから!
  • 32. Item 15: Use constexpr whenever possible. リテラル型 C++11 では、組み込み型は void を除いて全部OK! ユーザ定義型も一定の条件を満たせばOK! だってコンストラクタやメンバ関数も constexpr になれるから! …どゆこと?
  • 33. class Point { public: constexpr Point(double xVal = 0, double yVal = 0) noexcept : x(xVal), y(yVal) {} constexpr double xValue() const noexcept { return x; } constexpr double yValue() const noexcept { return y; } void setX(double newX) noexcept { x = newX; } void setY(double newY) noexcept { y = newY; } private: double x, y; }; Item 15: Use constexpr whenever possible.
  • 34. class Point { public: constexpr Point(double xVal = 0, double yVal = 0) noexcept : x(xVal), y(yVal) {} constexpr double xValue() const noexcept { return x; } constexpr double yValue() const noexcept { return y; } void setX(double newX) noexcept { x = newX; } void setY(double newY) noexcept { y = newY; } private: double x, y; }; Item 15: Use constexpr whenever possible. constexpr コンストラクタに コンパイル時定数を渡すと… 全てのメンバ変数が コンパイル時定数になる!
  • 35. class Point { public: constexpr Point(double xVal = 0, double yVal = 0) noexcept : x(xVal), y(yVal) {} constexpr double xValue() const noexcept { return x; } constexpr double yValue() const noexcept { return y; } void setX(double newX) noexcept { x = newX; } void setY(double newY) noexcept { y = newY; } private: double x, y; }; Item 15: Use constexpr whenever possible. constexpr コンストラクタに コンパイル時定数を渡すと… 全てのメンバ変数が コンパイル時定数になる! オブジェクト自体も コンパイル時定数に なる!
  • 36. Item 15: Use constexpr whenever possible. constexpr Point p1(9.4, 27.7); constexpr Point p2(28.8, 5.3); constexpr Point midpoint(const Point& p1, const Point& p2) noexcept { return { (p1.xValue() + p2.xValue()) / 2, (p1.yValue() + p2.yValue()) / 2 }; } constexpr auto mid = midpoint(p1, p2); constexpr オブジェクトを constexpr 関数の結果で初期化! コンパイル時定数!!! constexpr メンバ関数を呼ぶ! constexpr コンストラクタは コンパイル時に走る! コンパイル時定数!!!
  • 37. Item 15: Use constexpr whenever possible. constexpr Point p1(9.4, 27.7); constexpr Point p2(28.8, 5.3); constexpr Point midpoint(const Point& p1, const Point& p2) noexcept { return { (p1.xValue() + p2.xValue()) / 2, (p1.yValue() + p2.yValue()) / 2 }; } constexpr auto mid = midpoint(p1, p2); constexpr オブジェクトを constexpr 関数の結果で初期化! コンパイル時定数!!! constexpr メンバ関数を呼ぶ! constexpr コンストラクタは コンパイル時に走る! コンパイル時定数!!! 素晴らしい!
  • 38. Item 15: Use constexpr whenever possible. 今まで コンパイル時 ------ 超えられない壁 ------ 実行時 今 境界は曖昧に…
  • 39. Item 15: Use constexpr whenever possible. 今まで コンパイル時 ------ 超えられない壁 ------ 実行時 今 境界は曖昧に… 実行時処理をコンパイル時処理に マイグレーションすれば、 実行速度はより速くなる!!!
  • 40. Item 15: Use constexpr whenever possible. 今まで コンパイル時 ------ 超えられない壁 ------ 実行時 今 境界は曖昧に… 実行時処理をコンパイル時処理に マイグレーションすれば、 実行速度はより速くなる!!! でもコンパイル時間は長く…
  • 41. Item 15: Use constexpr whenever possible. 今まで コンパイル時 ------ 超えられない壁 ------ 実行時 今 境界は曖昧に… 実行時処理をコンパイル時処理に マイグレーションすれば、 実行速度はより速くなる!!! でもコンパイル時間は長く…
  • 42. Item 15: Use constexpr whenever possible. 今まで コンパイル時 ------ 超えられない壁 ------ 実行時 今 境界は曖昧に… 実行時処理をコンパイル時処理に マイグレーションすれば、 実行速度はより速くなる!!! でもコンパイル時間は長く…
  • 43. Item 15: Use constexpr whenever possible. (余談)ちなみに… constexpr コンストラクタの使い道は それだけじゃない! 静的オブジェクトの初期化順の問題の一部を解決できる! (@cpp_akira さんありがとう!!!) 詳しくは Webで! http://cpprefjp.github.io/reference/mutex/mutex/op_constructor.html (後でちょっとだけ出てくるよ!)
  • 44. Item 15: Use constexpr whenever possible. ところで… setX と setY は constexpr じゃないけど、 オブジェクトの値変更するんだから仕方ないよね…
  • 45. Item 15: Use constexpr whenever possible. そんなメンバ関数も、constexpr になれる。 そう、 C++14 ならね。
  • 46. Item 15: Use constexpr whenever possible. class Point { public: … constexpr void setX(double newX) noexcept // C++14 { x = newX; } constexpr void setY(double newY) noexcept // C++14 { y = newY; } … };
  • 47. Item 15: Use constexpr whenever possible. C++11 で constexpr に出来なかった理由は… その1:constexpr メンバ関数は暗黙で const 修飾! だから、オブジェクトの状態は変更できない! ⇒C++14 からは暗黙の const 修飾は亡くなりました! その2:戻り値の型 void はリテラル型じゃない! ⇒C++14では void もめでたくリテラル型になりました
  • 48. Item 15: Use constexpr whenever possible. (余談)Caution! constexpr メンバ関数の暗黙 const 修飾は C++14 で亡くなるので、 たとえ C++11 で書いていても constexpr メンバ関数には明示的に const 修飾しておきましょう!!! そうしないと、コンパイラが C++14 に移行した時に挙動が変わってしまい ます!!! (clang は 3.3 から警告が出ます)
  • 49. Item 15: Use constexpr whenever possible. (余談)ちなみに… constexpr な関数は暗黙で inline です! (実際、極限のインライン化ですよね…) だから、普通ヘッダで定義しておく。 (inline だから重複定義にならない) あと、constexpr として使うには宣言だけじゃなく定義が必要!
  • 50. Item 15: Use constexpr whenever possible. でも… セッタ関数 constexpr で何が嬉しいの?
  • 51. Item 15: Use constexpr whenever possible. こんな関数も書けるよ! // 点 p の原点に対する鏡映を返す(C++14) constexpr Point reflection(const Point& p) noexcept { Point result; result.setX(-p.xValue()); result.setY(-p.yValue()); return result; } 非 const の Point を作る x と y を設定する それのコピーを返す
  • 52. Item 15: Use constexpr whenever possible. 当然こんなこともできるよ! constexpr Point p1(9.4, 27.7); constexpr Point p2(28.8, 5.3); constexpr auto mid = midpoint(p1, p2); constexpr auto reflectedMid = reflection(mid); reflectedMid の値は (-19.1, -16.5) で、 コンパイル時に分かる このへんは前と一緒
  • 53. Item 15: Use constexpr whenever possible. さて、本項目のアドバイスの理由は明らかになったでしょ? 1. constexpr オブジェクトと constexpr 関数は、非 constexpr のものよりもより多くの文脈で使える。 2. constexpr を使う事で、あなたが作ったオブジェクトや関数の 使用可能なシチュエーションを最大化することができる。
  • 54. Item 15: Use constexpr whenever possible. Caution!!! constexpr はオブジェクトや関数の インタフェースの一部 だ! constexpr、それは "定数式が必要な箇所で使う事が出来る" という宣言
  • 55. Item 15: Use constexpr whenever possible. Caution!!! constexpr なオブジェクトや関数を提供 ⇓ クライアントコード内の定数式が必要な箇所で使われる ⇓ その後、constexpr を削除 ⇓ クライアントコードのコンパイルエラーが大量発生!!!
  • 56. Item 15: Use constexpr whenever possible. Caution!!! デバッグやチューニングのために I/O を追加しよ ⇓ 一般的に I/O は constexpr 関数内では許されていない ⇓ constexpr 取らなきゃ!!!
  • 57. Item 15: Use constexpr whenever possible. Caution!!! "whenever possible" は、 長期スパンで考えること!
  • 58. Item 15: Use constexpr whenever possible. 覚えておくこと • constexpr オブジェクトは、const で、コンパイル中に分かる値で 初期化される。 • constexpr 関数は、コンパイル時に分かる値を引数に呼び出すと、 コンパイル時に結果を生成する。 • constexpr オブジェクトと関数は、非 constexpr オブジェクトと 関数よりも、より幅広い文脈で使用することができる。 • constexpr はオブジェクトと関数のインタフェースの一部である。
  • 59. Item 15: Use constexpr whenever possible. さあ、 今日からあなたも constexpr で コンパイル時レイトレ!!!

Editor's Notes

  1. アラインメント指定は alignas 修飾子 alignof は型を取る式
  2. ちなみに、これまでの constexpr オブジェクトの例はみんな ODR-used じゃない…
  3. 計算結果が unspecified とか UB とか、あと条件によって constexpr 返さないってのもある。
  4. 計算結果が unspecified とか UB とか、あと条件によって constexpr 返さないってのもある。
  5. 再帰深度の問題とかもあるし…
  6. 実は、引数が constexpr オブジェクトじゃなくてもよい。
  7. 実は、引数が constexpr オブジェクトじゃなくてもよい。
  8. cpprefjp の mutex のコンストラクタのページにリンクあります!
  9. cpprefjp の mutex のコンストラクタのページにリンクあります!
  10. cpprefjp の mutex のコンストラクタのページにリンクあります!
  11. cpprefjp の mutex のコンストラクタのページにリンクあります!
  12. cpprefjp の mutex のコンストラクタのページにリンクあります!
  13. cpprefjp の mutex のコンストラクタのページにリンクあります!
  14. その1:中3女子さんがクソ仕様と言った奴ですね。
  15. これだけ見ると、あんまり嬉しくないんだけど… ローカル変数作って(当然 constexpr じゃない)、変更して、それを返したものが constexpr になるのが凄い!!!
  16. なんかあんまりありがたみが分からないんだよなぁ…