生成 constexpr 字符串表,不能产生常量表达式

Generate constexpr string table, cannot result in a constant expression

本文关键字:常量 表达式 不能 constexpr 字符串 生成      更新时间:2023-10-16

灵感来自 https://stackoverflow.com/a/37413361/1734357 我希望制作一个固定且已知大小的字符串颜色查找表,所以我不需要模板化它,但字符串不是 constexpr

怎么做呢?

struct Colors
{
constexpr Colors() : colors()
{
for (size_t i = 0; i < 256; i++)
colors[i] = "0;" + to_string(i) + ";255";
for (size_t i = 0; i < 256; i++)
colors[256 + i] = "0;255;" + to_string(255 - i);
for (size_t i = 0; i < 256; i++)
colors[2 * 256 + i] = to_string(i) + ";255;0";
for (size_t i = 0; i < 256; i++)
colors[3 * 256 + i] = "255;" + to_string(255 - i) + ";0";
}
string colors[4*256];
};

老实说,我会在 Python 脚本中执行此操作,生成一个C++源文件(由数组定义组成(作为预构建步骤。

这样,您就可以在编译时将信息烘焙到应用程序中,并且信息的来源仍然是易于修改的代码。

constexpr很好,但有时您只想自动生成一些代码。

问题是to_string返回 std::string,而 std::string 不是 constexpr 可构造的。

这个问题可以通过使用 Sprout constexpr 库来解决。尽管您可能会对编译时间感到失望。

#include <iostream>
#include <sprout/string.hpp>
#include <sprout/array.hpp>
#include <sprout/algorithm/transform.hpp>
#include <sprout/numeric/iota.hpp>
struct colorConv {
typedef sprout::string<20> result_type;
constexpr result_type
operator()(int n) const {
return n / 256 == 0 ? "0;" + sprout::to_string(255 - n) + ";255"
: n / 256 == 1 ? "0;255;" + sprout::to_string(2 * 255 + 1 - n)
: n / 256 == 2 ? sprout::to_string(3 * 255 + 2 - n ) + ";255;0;"
: "255;" + sprout::to_string(4 * 255 + 3 - n) + ";0";
}
};
struct Colors {
private:
typedef colorConv::result_type string;
constexpr static auto source = sprout::iota<sprout::array<int, 256*4> >(0);
public:
constexpr static auto colors = sprout::transform<sprout::array<string, 256*4> >(
sprout::begin(source),
sprout::end(source),
colorConv()
);
};
int main() {
auto& a = Colors::colors;
for (auto&& str : Colors::colors) {
std::cout << str << std::endl;
}
return 0;
}