web-dev-qa-db-ja.com

std :: stringは結局コンパイル時の文字列になりますか?

多くの開発者やライブ​​ラリの作成者は、かなり長い間、コンパイル時の文字列に苦労しています。標準(ライブラリ)文字列std::stringは動的メモリ割り当てを必要とし、constexprではありません。

したがって、コンパイル時の文字列を正しく取得する方法についての質問とブログ投稿がたくさんあります。

newconstexprコードで利用できるだけでなく、コンパイル時に動的に割り当てることができるだけでなく、実際には std::stringがconstexpr in C++ 2 (Herb SutterによるC++標準ワーキンググループ会議レポート)。

それは、C++ 20以降のコードの場合、これらの気の利いたコンパイル時文字列実装をすべてチャックし、常にstd::stringを使用する必要があることを意味しますか?

そうでない場合-いつそうするのか、そしていつ(今日の下位互換性コードを除いて)今日可能なことをいつ実行するのか?


注:内容がそのタイプの一部である文字列について話しているのではありません。つまり、notstd::integral_constantの同等物について話しているのではありません。それは間違いなくstd::stringにはなりません。

18
einpoklum

「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_を(直接)使用するのではなく、これらの問題を解決します。

12
Nicol Bolas