Есть ли стандартный способ сохранить результат функции Contexpr Std :: String?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Есть ли стандартный способ сохранить результат функции Contexpr Std :: String?

Сообщение Anonymous »

c ++ разрешает функции contexpr , которые возвращают std :: string . Например, используя Magic_enum , чтобы получить разделенную пространственную строку, содержащую все значения перечисления.

Код: Выделить всё

template 
static constexpr std::string GetAllEnumNamesAsString()
{
const std::string space = " ";
constexpr std::array names = magic_enum::enum_names();
std::string all{ names[0] };
for (int i = 1; i < names.size(); i++)
all += (space + std::string{ names[i] });

return all;
}
Проблема заключается в том, что строка может использоваться в функции contexpr , вы не можете объявить строку constexpr , поскольку она использует кучу. Таким образом, код, используя эту возвращенную строку, может объявить ее только как const . Я думал, что компилятор, по крайней мере, будет использовать функцию contexpr для вычисления окончательного буфера строк и поместить ее в статическое хранилище, но как GCC, так и MSVC просто делегируют весь вызов для выполнения, что приведет к созданию тонны постороннего кода. Ссылка на Godbolt: < /p>

Код: Выделить всё

int main()
{
// must be allowed at compile time because it's part of a static_assert
static_assert(GetAllNames().length() == 17);

// but compiler makes this pure runtime - not even the final string is placed in static storage to copy to the heap
const std::string names = GetAllNames();
printf("%s\n", names.c_str());

return 0;
}
< /code>
Как лучше всего обойти это, чтобы использовать строковый буфер с составщиком компилятора? В моем ограниченном понимании Contexpr 
позволяет std :: string как «переход», поэтому нам нужно скопировать его из строки, где -то до того, как функция, которая использует строку, будет уничтожена (на std :: ray?). Хитрость здесь заключается в том, что вы не можете использовать переменную в качестве параметра шаблона. Чтобы обойти это, нам просто нужно ... дважды вызвать функцию? Следующее работает, но я, должно быть, что -то упускаю - есть ли уже что -то стандартное для этого? Или, по крайней мере, лучший способ не «выбрасывать» всю работу, которую компилятор может выполнить в функциях contexPR, возвращающих строку? < /P>

Код: Выделить всё

template 
class FakeStringView
{
public:
constexpr FakeStringView(const std::string_view& s1) : _array{}
{
for (auto i = 0; i < s1.length(); ++i)
_array[i] = s1[i];
}

constexpr std::string_view Get() const
{
return { _array.data(), _array.size() };
}

private:
std::array _array;
};

template 
constexpr auto GetAllNames()
{
// call it twice - once for length and once for the string
return FakeStringView(GetAllNamesImpl());
}

constexpr auto fakestringview = GetAllNames();
std::cout 

Подробнее здесь: [url]https://stackoverflow.com/questions/79545997/is-there-a-standard-way-to-keep-the-result-of-a-constexpr-stdstring-function[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»