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]
c ++ позволяет функциям contexpr, которые возвращают std :: string. Например, используя magic_enum (https://github.com/neargye/magic_enum), чтобы получить космированную строку, содержащую все значения перечисления. [code]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]; }