site
site copied to clipboard
CWG 2518の影響調査
static_assert(false, "was wrong"); - yohhoyの日記
#include <type_traits> template <typename T> T doubling(T x) { if constexpr (std::is_integral_v<T> || std::is_floating_point_v<T>) { // 算術型の場合は2倍した値を返す return x * T{2}; } else { // それ以外の型はコンパイルエラー static_assert(false); // NG(CWG 2518適用前) // CWG 2518適用後は上記記述でOK } }
constexpr if文に影響ありそう
https://twitter.com/yohhoy/status/1759832908834238510 en.cppreference.com/w/cpp/language… ではC++11まで遡及適用していますね。issueくらい作っておいた方がよさげ。
https://x.com/yumetodo/status/1629847372523266049?s=20
ふあっ!? それどういう解釈をしてるんだ
https://x.com/yohhoy/status/1630051035011227648
(C++TMPに洗脳されてない)ユーザ視点では許容されるほうが自然ですね( ^o^)ノ 仕様的にはインスタンス化されない方の分岐にあるstatic_assertを定義時には無視するだけ
https://x.com/yumetodo/status/1630051562881175552?s=20
あー、static_assertを破棄文で評価しないみたいな特別扱いということか
https://x.com/yohhoy/status/1630057226529558529?s=20
まさに特別扱いですね https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2593r1.html だと「static_assertの条件式は(暗黙に)テンプレートパラらメータ依存式とみなす」と解釈させるみたいですが、実際のWording(CWG2518)は恐ろしくあっさりしてて難解
@yohhoy 書いてみたんですがお手隙のときに見てもらってもいいでしょうか?
https://github.com/cpprefjp/site/commit/79fc60a46544883f2f132639a33ff68adb99e3d4#r139029850
if constexpr を更新した時に discarded statement の訳語は廃棄文とすることにしていました。
あっ
5ae498212b279218f89ee9a21bd0e901ce9a716c
で対応しました。 @akinomyoga
https://github.com/cpprefjp/site/commit/79fc60a46544883f2f132639a33ff68adb99e3d4#r139029850
後この節の内容は前の節の "2段階名前探索における注意点" とちゃんと統合するべきの気がします。つまり、"2段階名前探索における注意点" の中で今「static_assert(false) はダメ」って説明しているところで CWG 2518 以降は例外として static_assert(false) OKってことも言うべきの気がします。
でも…遡って適用ならば、むしろ、説明は逆の方が良い気がします。つまり、最初の説明で static_assert(false) はOKって説明して、但し書きで CWG 2518 適用以前はダメだったという具合に。
これ難しいんですよね。今回のってあくまでstatic_assertに関してのみ例外条項を作ったという建付けなので、別に「2段階名前探索における注意点」そのものは変わってないんですよね。どっちかというと例示を変えて全面刷新しないといけないかもしれない・・・。ただ実用的な例がないのではという思いも・・・
ありがとうございます!
多分古のBOOST_STATIC_ASSERT
(不完全型のsizeofがエラーになるのを利用したやつ)を使ってstatic_assert
と比較させれば、厳密な説明にはなる気はしています、ただし需要がなさそうなので尻込みしています。
これ難しいんですよね。今回のってあくまでstatic_assertに関してのみ例外条項を作ったという建付けなので、別に「2段階名前探索における注意点」そのものは変わってないんですよね。どっちかというと例示を変えて全面刷新しないといけないかもしれない・・・。
また記事を見てよく分からなくなったのですがこの "注意点" って何のことを言っているのですか。"2段階名前解決があるという事実自体" が注意点なのか、それともそれを踏まえて "static_assert(false) が罠" ということが注意点なのか。今の「2段階名前探索における注意点」の内容的には主に後者のような気がしています (でも最後の例は何か違うことを書いている…)。
もし "2段階名前解決が起こるという事実自体" を説明するのだとしたら例示は全部作り直しですね。
ただ実用的な例がないのではという思いも・・・
うーん。普通にあるような気がします。
template<typename A> int func(A const& a) {
if constexpr (... /* A::foo がある条件 */) {
return a.foo();
} else {
return a.bar();
}
}
とかでいいのでは。
うーん。普通にあるような気がします。
あー・・・。
まあ変数aが依存名だから遅延されるわけですよね。
https://wandbox.org/permlink/LB5hpsMh2bjQklGF
@yumetodo さん: 79fc60a46544883f2f132639a33ff68adb99e3d4 へのコメント記載しました。
if_constexpr.md の「2段階名前探索における注意点」に関しては、全面的なアップデートをするならば下記文章構造が望ましいとは思います。プログラマにとって自然な CWG 2518 適用後の状態を前提としています。
- ベース仕様を説明(現状通り)
- 2段階名前探索における注意点を記載(static_assert への言及のみ分離)
- static_assert については特例措置が設けられ、期待通り動くことを説明
- CWG 2518適用以前には必要とされるワークアラウンドを記述
https://github.com/cpprefjp/site/commit/79fc60a46544883f2f132639a33ff68adb99e3d4 へのコメント記載しました。
49f914073a7b69b19b48acb6c0fb4c3d612a4b09 で反映しました
全面的なアップデートをするならば下記文章構造が望ましいとは思います。
週末時間が取れたらやってみます
@yumetodo さん コメント反映ありがとうございます。
文章構成のオーバーホールまで手を付けるご予定なら、Pull Reqeustの形をとっていただいた方がスムースかもしれませんね。 こちらの Issue は単体でCLOSEして良いかなと考えたのですが、いかがでしょ。
PR立てたら閉じます。