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

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

Сообщение Anonymous »

c ++ позволяет функциям contexpr, которые возвращают std :: string. Например, используя magic_enum (https://github.com/neargye/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;
}
< /code>
Проблема заключается в том, что строка может использоваться в функции contexpr, вы не можете объявить строку contexpr, поскольку она использует кучу.  Таким образом, код, используя эту возвращенную строку, может объявить ее только как const.  Я думал, что компилятор, по крайней мере, будет использовать функцию ContexPR для расчета конечного буфера строк и поместить ее в статическое хранилище, но как GCC, так и MSVC просто делегируют весь вызов для выполнения, что приводит к созданию тонны постороннего кода.  Ссылка на Godbolt, Main в строке 1542 из -за вставки в Magic_enum.hpp: https://godbolt.org/z/j1f9cct93.
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>
Как лучше всего обойти это, чтобы использовать строковый буфер с составщиком компилятора?  В моем ограниченном понимании ConstexPR позволяет std :: string как «переход», поэтому нам нужно скопировать его из строки где -то, прежде чем функция, которая использует строку, будет уничтожена (на std :: массив?).  Хитрость здесь заключается в том, что вы не можете использовать переменную в качестве параметра шаблона.  Чтобы обойти это, нам просто нужно ... позвонить по функции дважды?  Следующее работает, но я, должно быть, что -то упускаю - есть ли уже что -то стандартное для этого?  Или, по крайней мере, лучший способ не «выбрасывать» всю работу, которую компилятор может выполнить в функциях 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++»