質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

472閲覧

ラムダ式のstatic_assertでの挙動

alphya

総合スコア124

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

2クリップ

投稿2018/12/27 16:58

static_assertのラムダ式での挙動

 先日Qiitaに記事を投稿したのですが、static_assertの条件式で[]{return false;}()を使ったときもtwo-phase name lookupの2phase目と思われるときに評価されるコンパイラの挙動は規格的に信用してもいいのでしょうか。

 総称ラムダの場合、[temp.inst]/10に

...総称ラムダのインスタンス化は、呼び出し演算子テンプレートがインスタンス化されない限り、その複合ステートメント内のif constexprステートメントのサブステートメントのインスタンス化を必要としません。...

(google翻訳を少し編集)

とあるのですが...

Thanks for any help! :)

該当のソースコード

cpp

1if constexpr (true); 2else static_assert([]{return false;}(), "..."); // 評価される?
yohhoy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yumetodo

2018/12/27 17:34

個人的にはただのlambdaは依存名じゃないから破棄文になるまえに評価されてstatic_assert発動説を推しておきたい。clangとmsvc19.16はそんな感じの実装。gccはerror: could not convert '<lambda closure object>main()::<lambda()>{}.main()::<lambda()>()' from 'void' to 'bool'とか言ってて意味わからん。
alphya

2018/12/27 17:53

yometodoさん、コメントありがとうございます! 手元でwandboxで、main関数内に書いて実行してみたところ、確かにそんな出力になりました! Qiitaの記事内での文脈で使うとコンパイルエラーにならなかったので、ちょっと不思議だったのですが、これはコンパイラのバグかもしれないですね... わざわざ規格でgeneric lambdaを指定しているあたり、私もstatic_assert発動説が有力だと思います!
yumetodo

2018/12/27 17:56

ところで規格ってどれ見てますか?n4659見てるんですが[temp.inst]/10にお示しのような内容を見つけられない
alphya

2018/12/27 18:03

n4741です!n4659だと[temp.inst]/11?..(多分違う...)
yumetodo

2018/12/27 18:06 編集

4741ってすごい中途半端では・・・。C++2aという意味合いなら4791あたりを見てくるべきでは n4659だと[temp.inst]/9だった、一個上に気が付かない集中力なのでネます
yumetodo

2018/12/28 05:12

githubの方にあるかなと
alphya

2018/12/28 05:29

yumetodoさん githubに新しいものがあるとは知りませんでした! ありがとうございました!!
guest

回答1

0

ベストアンサー

こんにちは。

もともとconstexpr ifはテンプレート引数に依存しているものの実体化を遅延する効果がありますが、提示されているコードはテンプレート引数がそもそもないので、実体化の遅延効果は期待できないと思います。

そして、N4171の該当のNoteは「ジェネリックラムダ」についての注意書きですね。
ご提示のコードはジェネリックラムダではないので定義した時点で実体化されます。

文脈的に下記のようなケースを想定した注意書きのような気がします。(通常のラムダはテンプレートではないですが、ジェネリックラムダはテンプレートなので、その辺りを特記した。)

C++

1#include <type_traits> 2 3int main() 4{ 5 auto assert_int = 6 [](auto x) 7 { 8 if constexpr (std::is_integral<decltype(x)>{}); 9 else static_assert(std::is_integral<decltype(x)>{}, "..."); 10 }; 11 assert_int(123); 12// assert_int("abc"); // static_assert!! 13}

投稿2018/12/28 04:42

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

alphya

2018/12/28 05:26

Chironianさん、回答ありがとうございます! 私もChironianさんの回答のように考えていましたが、Clangまで定義した時点で実体化させないケースがあったので、違った評価の仕方があるのではと思い質問させて頂きました。また、N4171のNoteに関しては完全に解釈を間違えてました...すみませんでした。・゚゚・(>д<;)・゚゚・。 Chironianさん、この度もありがとうございました!! また機会がありましたらよろしくお願いいたします! All your help has been great! :)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問