web-dev-qa-db-ja.com

constexprでstd :: stringを使用することは可能ですか?

C++ 11、Ubuntu 14.04、GCCデフォルトツールチェーンを使用

このコードは失敗します:

constexpr std::string constString = "constString";

エラー:constexpr変数「constString」のタイプ「const string {aka const std :: basic_string}」はリテラルではありません...「... std :: basic_string」には非自明なデストラクタがあります

Aconstexprstd::stringを使用することはできますか? (明らかにそうではない...)もしそうなら、どのように? constexprで文字列を使用する別の方法はありますか?

125
Vector

いいえ、そしてあなたのコンパイラはすでにあなたに包括的な説明を与えました。

しかし、あなたはこれを行うことができます:

constexpr char constString[] = "constString";

実行時に、これを使用して、必要なときにstd::stringを構築できます。

126
tenfour

C++ 17では、 string_view を使用できます。

constexpr std::string_view sv = "hello, world";

string_viewは、 string のようなオブジェクトで、charオブジェクトのシーケンスへの不変の非所有参照として機能します。

95
Joseph Thomson

問題は非自明なデストラクタであるため、デストラクタがstd::stringから削除された場合、そのタイプのconstexprインスタンスを定義することができます。このような

struct constexpr_str {
    char const* str;
    std::size_t size;

    // can only construct from a char[] literal
    template <std::size_t N>
    constexpr constexpr_str(char const (&s)[N])
        : str(s)
        , size(N - 1) // not count the trailing nul
    {}
};

int main()
{
    constexpr constexpr_str s("constString");

    // its .size is a constexpr
    std::array<int, s.size> a;
    return 0;
}
16
neuront

C++ 20はconstexpr文字列とベクトルを追加します

次の提案 受け入れられました どうやら: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0980r0.pdf および次のようなコンストラクタを追加します。

// 20.3.2.2, construct/copy/destroy
constexpr
basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) { }
constexpr
explicit basic_string(const Allocator& a) noexcept;
constexpr
basic_string(const basic_string& str);
constexpr
basic_string(basic_string&& str) noexcept;

すべて/ほとんどのメソッドのconstexprバージョンに加えて。

GCC 9.1.0の時点ではサポートはありません。以下はコンパイルに失敗します。

#include <string>

int main() {
    constexpr std::string s("abc");
}

で:

g++-9 -std=c++2a main.cpp

エラーあり:

error: the type ‘const string’ {aka ‘const std::__cxx11::basic_string<char>’} of ‘constexpr’ variable ‘s’ is not literal

std::vectorで議論されました: constexpr std :: vectorを作成できません

Ubuntu 19.04でテスト済み。