Ответ 1
Нет, и ваш компилятор уже дал вам исчерпывающее объяснение.
Но вы можете сделать это:
constexpr char constString[] = "constString";
Во время выполнения это может быть использовано для построения std::string
при необходимости.
Использование С++ 11, Ubuntu 14.04, инструментальная привязка по умолчанию GCC.
Этот код не работает:
constexpr std::string constString = "constString";
error: тип 'const string {aka const std:: basic_string} of constexpr variable 'constString не является литералом... потому что... 'Std:: basic_string имеет нетривиальный деструктор
Можно ли использовать std::string
в constexpr
? (видимо, нет...) Если да, то как? Есть ли альтернативный способ использования символьной строки в constexpr
?
Нет, и ваш компилятор уже дал вам исчерпывающее объяснение.
Но вы можете сделать это:
constexpr char constString[] = "constString";
Во время выполнения это может быть использовано для построения std::string
при необходимости.
В С++ 17 вы можете использовать string_view
:
constexpr std::string_view sv = "hello, world";
A string_view
- это объект string
-like, который действует как неизменяемая, не обладающая ссылкой на любую последовательность объектов char
.
Так как проблема - нетривиальный деструктор, поэтому, если деструктор удален из 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;
}
С++ 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.