66484


興味本位であり、実用コードが有るわけでもないのですが質問させて下さい

例えば以下のコードです

[code]

    class hoge{
        //...
    };
    
    template<
        std::enable_if_t<is_constexpr_type<hoge>,std::nullptr_t> = nullptr //←is_constexpr_typeを実現する方法は有るか
    > 
    isConstexpr(){
        //...
    }
    
    
[/code]

このように、コンパイル時にconstexpr変数として振る舞える型かを確認する方法は有りますか？

また(ついでに分かればお伺いしたいのですが)、std::is_literal_typeが削除された事は上記の結果に関わるものですか？  
(C++17時点で削除が決定していたのか、C++20で対策が確立されたので削除されたのか)


CC BY-SA 4.0
2020-05-10T07:38:04.273
66481
2020-05-10T21:19:42.043
24599
question
c++
C++20以降で、ある型がconstexpr変数として振る舞えるかを確認する方法はありますか？


[std::is_literal_type](https://cpprefjp.github.io/reference/type_traits/is_literal_type.html)にまとめられています。C++14で`void`を対象に追加、C++17で非推奨、C++20で削除とのことです。

> # 非推奨・削除の詳細
>
>
> この型特性は、ジェネリックコードにおいて特定の型が`constexpr`に振る舞えるかを判定する機能を持つが、ユーザー定義型の場合には「少なくとも一つ以上の`constexpr`コンストラクタを持つこと」という条件になっていた。しかし、いずれかのコンストラクタが`constexpr`で、それ以外が`constexpr`コンストラクタではなく、それに意味がある場合に、この型特性は使いにくかった。
>
>
> 実際に必要となるのは、特定の型が`constexpr`に振る舞えるかではなく、特定の構築処理で定数初期化ができるかであるため、リテラル型という考え方は廃止すべきである、という結論になった。

とのことです。

* * *

> std::is_literal_typeの代替案(リテラル型に変わる概念)及びその実現方法がC++20以降に有るか。

上記の通り、型がリテラルであるかどうかという考え方が不適切という判断です。そのため廃止に向けた手順として、C++17で非推奨化、C++20で削除という動きになっています。当然、C++17の時点でその判断がされています。

これも上記の通りなのですが、代替案ではなく、型がリテラルかどうかではなく、コンストラクタが`constexpr`かどうかで判断すべきです。同じ型であってもコンストラクタのオーバーロードによって異なるためです。

なお、式が`constexpr`かどうかを判断する方法として[Is it possible to know when is constexpr really
a constexpr?](https://stackoverflow.com/a/46920091/4315484)で次の方法が紹介されていました。

[code]

    template <class T>
    constexpr void test_helper(T&&) {}
    
    #define IS_CONSTEXPR(...) noexcept(test_helper(__VA_ARGS__))
    
[/code]

キーワード[`noexcept`](https://cpprefjp.github.io/lang/cpp11/noexcept.html)には２つの機能があり、

  * 例外仕様としてのnoexcept
  * 式が例外を送出する可能性があるか判定するnoexcept演算子

後者を利用します。`constexpr`式は例外を出さないためnoexcept演算子に与えた場合、`true`を返します。`constexpr`式でなかった場合は例外を出すかどうかは式に依存します。そこで`test_helper`を使用し例外が必ず出ると判断させることで`false`を得ます。


CC BY-SA 4.0
2020-05-10T09:18:14.073
66484
2020-05-10T21:19:42.043
2020-05-10T21:19:42.043
4236
4236
66481
answer