Arm*_*gny 6 c++ arrays templates constexpr string-view
我想创建一个constexpr std::array<std::string_view, ConstexprNumber>. 例如,它应该包含constexpr std::strings_view's如下内容:
"text0", "text1", "text2", ..... "textn"
我想出了以下初始解决方案:
#include <iostream>
#include <array>
#include <utility>
#include <string>
#include <string_view>
// Number of strings that we want to generate
constexpr size_t NumberOfTextsToGenerate = 10u;
// constexpr function to build a string
constexpr std::string_view makeString(unsigned int i) {
return std::string_view("text");
}
// Helper: constexpr function that will create an array of string_views and initialize it
template <unsigned int... ManyIntegers>
constexpr auto generateTextHelper(std::integer_sequence<unsigned int, ManyIntegers...>) {
return std::array<std::string_view, sizeof...(ManyIntegers)>{ {makeString(ManyIntegers)...}};
}
// Helper: constexpr function that will return an array of string_views as shown above with a specified number of texts
constexpr auto generateTextArray() {
return generateTextHelper(std::make_integer_sequence<unsigned int, NumberOfTextsToGenerate>());
}
// This is a definition of a std::array<std::string_view,UpperBound> initialized with some text
constexpr auto text = generateTextArray();
int main() {
for (size_t i{}; i < NumberOfTextsToGenerate; ++i)
std::cout << text[i] << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,当然“makeString”函数不会做我想要的。或者,更好地说,我不知道如何实施正确的解决方案。
我们怎样才能让这样的数组工作呢?是基于这个初始解决方案还是类似的东西?
我现在找到了一个最终满足我需求的解决方案。
由于 SO 用户的许多很好的答案以及我的问题的其他答案,
我现在将使用以下代码。
#include <iostream>
#include <algorithm>
#include <iterator>
#include <array>
#include <string>
// Specification for the output that we want to generate
constexpr const char BaseString[]{ "text" }; // Some example text
constexpr size_t StartIndex = 1u; // Start index. So first array element will be "Text1"
constexpr size_t NumberOfElements = 20u; // Number of elements to create. Last array element will be "Text20"
// These templates are used to generate a std::array
namespace ConstexprGenerator {
// To create something like "text123" as constexpr
template <const size_t numberToConvert, const char* Text>
class Converter {
public:
// Some helper variables for calculating sizes
static constexpr size_t TextLength{ std::char_traits<char>::length(Text) };
static constexpr size_t NumberOfDigits{ ([]() constexpr noexcept {size_t result = 0; int temp = numberToConvert; for (; temp != 0; temp /= 10) ++result; return result; }()) };
static constexpr size_t ArrayLength{ (numberToConvert ? 1u : 2u) + NumberOfDigits + TextLength };
// Here we will store the string
std::array<char, ArrayLength> internalString{};
// Constructor: Copy text and Convert number to character digits
constexpr Converter() noexcept {
size_t i{ 0 }; for (; i < TextLength; ++i) internalString[i] = Text[i]; // Copy text
if (numberToConvert == 0) internalString[i] = '0'; // In case that the given number is 0, then simply copy '0' character
else {
i = NumberOfDigits + TextLength - 1; // Convert number to character digits
int number = numberToConvert; for (; number; number /= 10)
internalString[i--] = number % 10 + '0';
}
}
constexpr std::array<char, ArrayLength> get() const { return *this; }; // getter
constexpr operator std::array<char, ArrayLength>() const { return internalString; } // type cast
};
// Templated variable. Will have always a different type, depending on the template parameters
template<const size_t numberToConvert, const char* Text>
constexpr auto Converted = Converter<numberToConvert, Text>{}.get();
// Generate a std::array with n elements that consist of const char *, pointing to Textx...Texty
template <int... ManyIntegers>
constexpr auto generateTextHelper(std::integer_sequence<size_t, ManyIntegers...>) noexcept {
return std::array<const char*, sizeof...(ManyIntegers)>{ {Converted<ManyIntegers + StartIndex, BaseString>.data()...}};
}
// Generate the required number of texts
constexpr auto generateTextArray()noexcept {
return generateTextHelper(std::make_integer_sequence<size_t, NumberOfElements>());
}
}
// This is a constexpr array
constexpr auto text = ConstexprGenerator::generateTextArray();
int main() {
std::copy(text.begin(), text.end(), std::ostream_iterator<const char*>(std::cout, "\n"));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用 MSVC、Clang 和 gcc 进行测试