是否可以在constexpr中使用std :: string?

时间:2014-11-25 09:44:42

标签: c++11 stdstring constexpr

使用C ++ 11,Ubuntu 14.04,GCC默认工具链

此代码失败:

constexpr std::string constString = "constString";
  

错误:类型'const string {aka const std :: basic_string}'   constexpr变量'constString'不是文字...因为......   'std :: basic_string'有一个非平凡的析构函数

是否可以在std::string中使用constexpr? (显然不是......)如果是这样,怎么样?是否有另一种方法可以在constexpr中使用字符串?

5 个答案:

答案 0 :(得分:125)

不,你的编译器已经给你一个全面的解释。

但你可以这样做:

constexpr char constString[] = "constString";

在运行时,可以在需要时使用它来构造std::string

答案 1 :(得分:95)

在C ++ 17中,您可以使用string_view

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

string_view是一个类似string的对象,它充当对任何char个对象序列的不可变的非拥有引用。

答案 2 :(得分:16)

由于问题是非平凡的析构函数,因此如果从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;
}

答案 3 :(得分:11)

C ++ 20将添加constexpr字符串和向量

以下建议has been accepted显然是: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在以下地方讨论:Cannot create constexpr std::vector

在Ubuntu 19.04中测试。

答案 4 :(得分:0)

Ciro 的回答很有帮助地指出了 P0980,它被列为 here 作为 C++20 库功能,仅受 MSVC STL 19.29 (16.10) 支持,当时没有其他编译器支持这个写作。我在 Godbolt 上通过 11.1 版测试了 GCC 编译器,并且简单的 constexpr std::strings 在该版本中仍然会产生错误。