cpprefjp / site

cpprefjpサイトのMarkdownソース
https://cpprefjp.github.io/
381 stars 155 forks source link

CWG 2518の影響調査 #1257

Closed yumetodo closed 6 months ago

yumetodo commented 7 months ago

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くらい作っておいた方がよさげ。

yumetodo commented 7 months ago

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)は恐ろしくあっさりしてて難解

yumetodo commented 7 months ago

@yohhoy 書いてみたんですがお手隙のときに見てもらってもいいでしょうか?

yumetodo commented 7 months ago

https://github.com/cpprefjp/site/commit/79fc60a46544883f2f132639a33ff68adb99e3d4#r139029850

if constexpr を更新した時に discarded statement の訳語は廃棄文とすることにしていました。

あっ

5ae498212b279218f89ee9a21bd0e901ce9a716c

で対応しました。 @akinomyoga

yumetodo commented 7 months ago

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段階名前探索における注意点」そのものは変わってないんですよね。どっちかというと例示を変えて全面刷新しないといけないかもしれない・・・。ただ実用的な例がないのではという思いも・・・

akinomyoga commented 7 months ago

ありがとうございます!

yumetodo commented 7 months ago

多分古のBOOST_STATIC_ASSERT(不完全型のsizeofがエラーになるのを利用したやつ)を使ってstatic_assertと比較させれば、厳密な説明にはなる気はしています、ただし需要がなさそうなので尻込みしています。

akinomyoga commented 7 months ago

これ難しいんですよね。今回のってあくまで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();
  }
}

とかでいいのでは。

yumetodo commented 7 months ago

うーん。普通にあるような気がします。

あー・・・。

まあ変数aが依存名だから遅延されるわけですよね。

https://wandbox.org/permlink/LB5hpsMh2bjQklGF

yohhoy commented 7 months ago

@yumetodo さん: 79fc60a46544883f2f132639a33ff68adb99e3d4 へのコメント記載しました。


if_constexpr.md の「2段階名前探索における注意点」に関しては、全面的なアップデートをするならば下記文章構造が望ましいとは思います。プログラマにとって自然な CWG 2518 適用後の状態を前提としています。

yumetodo commented 7 months ago

https://github.com/cpprefjp/site/commit/79fc60a46544883f2f132639a33ff68adb99e3d4 へのコメント記載しました。

49f914073a7b69b19b48acb6c0fb4c3d612a4b09 で反映しました


全面的なアップデートをするならば下記文章構造が望ましいとは思います。

週末時間が取れたらやってみます

yohhoy commented 7 months ago

@yumetodo さん コメント反映ありがとうございます。

文章構成のオーバーホールまで手を付けるご予定なら、Pull Reqeustの形をとっていただいた方がスムースかもしれませんね。 こちらの Issue は単体でCLOSEして良いかなと考えたのですが、いかがでしょ。

yumetodo commented 7 months ago

PR立てたら閉じます。