多くの開発者やライブラリの作成者は、かなり長い間、コンパイル時の文字列に苦労しています。標準(ライブラリ)文字列std::string
は動的メモリ割り当てを必要とし、constexprではありません。
したがって、コンパイル時の文字列を正しく取得する方法についての質問とブログ投稿がたくさんあります。
new
がconstexpr
コードで利用できるだけでなく、コンパイル時に動的に割り当てることができるだけでなく、実際には std::string
がconstexpr in C++ 2 (Herb SutterによるC++標準ワーキンググループ会議レポート)。
それは、C++ 20以降のコードの場合、これらの気の利いたコンパイル時文字列実装をすべてチャックし、常にstd::string
を使用する必要があることを意味しますか?
そうでない場合-いつそうするのか、そしていつ(今日の下位互換性コードを除いて)今日可能なことをいつ実行するのか?
注:内容がそのタイプの一部である文字列について話しているのではありません。つまり、notstd::integral_constant
の同等物について話しているのではありません。それは間違いなくstd::string
にはなりません。
「constexpr文字列」の意味によって異なります。
C++ 20で実行できるのは、constexpr
(またはconsteval
)とマークされた関数内で_std::string
_を使用することです。そのような関数は、他のリテラル型と同じように、string
の作成、操作などを行うことができます。ただし、その文字列がconstexpr
以外のコードに漏れることはありません。これは非一時的な割り当てであり、禁止されています。
実は、あなたが与えるすべての例は、文字列をテンプレートパラメータとして使用する試みです。それは似ているがまだ異なるものです。コンパイル時の文字列の作成について話しているだけではありません。これを使用して、テンプレートをインスタンス化します。
C++ 20は、ユーザー定義型をテンプレートパラメータにすることでこの問題を解決します。ただし、そのような型の要件は、単なるリテラル型である場合よりもはるかに厳格です。タイプには 非パブリックメンバーはなく、唯一のメンバーはこれらの制限に従うタイプのもの が必要です。基本的に、コンパイラーは、そのデータメンバーのバイト単位の比較が同等の値を表すことを知る必要があります。そして、constexpr
対応の_std::string
_でも、そのようには機能しません。
しかし、_std::array<char, N>
_はそれを行うことができます。そしてconstexpr
コードを使用している場合は、constexpr
関数を呼び出して_std::string
_を返し、その文字列をconstexpr
値に格納してから、string::size()
はconstexpr
関数です。したがって、これを使用して、配列のN
を埋めることができます。
文字を_constexpr array
_にコピーする(これはconstexpr
値なので不変です)少し複雑ですが、実行可能です。
したがって、C++ 20は_std::string
_を(直接)使用するのではなく、これらの問題を解決します。