简体   繁体   English

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

[英]Generate constexpr string table, cannot result in a constant expression

Inspired in https://stackoverflow.com/a/37413361/1734357 I wish to make a string color lookup table of a fixed and known size, so I shouldn't need to template it, but string isn't constexpr受到https://stackoverflow.com/a/37413361/1734357 的启发,我希望制作一个固定且已知大小的字符串颜色查找表,因此我不需要对其进行模板化,但字符串不是 constexpr

How to go about it?怎么办?

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];
};

The problem is that to_string returns std::string, and std::string is not constexpr constructable.问题是 to_string 返回 std::string,而 std::string 不是 constexpr 可构造的。

This issue can be solved by using Sprout constexpr library .这个问题可以通过使用Sprout constexpr 库来解决。 Although you might be disappointed by the compilation time.尽管您可能会对编译时间感到失望。

#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;
}

Quite honestly, I'd do this in a Python script, generating a C++ source file (consisting of an array definition) as a pre-build step.老实说,我会在 Python 脚本中执行此操作,生成 C++ 源文件(由数组定义组成)作为预构建步骤。

That way, you get the information baked into your application at compile time, and the source for the information is still code so easy to modify.这样,您就可以在编译时将信息整合到您的应用程序中,并且信息的来源仍然是易于修改的代码。

constexpr is fine but sometimes you just want to auto-generate some code. constexpr很好,但有时您只想自动生成一些代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 MSVC constexpr函数'xyz'不能导致常量表达式 - MSVC constexpr function 'xyz' cannot result in a constant expression constexpr - 函数不能用于常量表达式 - constexpr - function cannot be used in a constant expression 生成 constexpr 数组(错误:'sum' 的值在常量表达式中不可用) - Generate constexpr array (error: the value of 'sum' is not usable in a constant expression) 通过引用调用constexpr方法 - 结果是一个常量表达式吗? - Calling a constexpr method through a reference - is the result a constant expression? static_casting的结果是constexpr void *一个常量表达式吗? - Is the result of static_casting a constexpr void* a constant expression? 错误! constexpr 变量必须由常量表达式 constexpr 初始化 - Error! constexpr variable must be initialized by a constant expression constexpr 什么决定了 constexpr function 是否是常量表达式? - What determines whether a constexpr function is a constant expression? constexpr 变量必须由常量表达式初始化 - constexpr variable must be initialized by a constant expression 初始化constexpr-“用非常量表达式非法初始化&#39;constexpr&#39;实体” - Initialising constexpr - “ illegal initialization of 'constexpr' entity with a non-constant expression” 返回常量表达式不需要constexpr函数吗? - A constexpr function is not required to return a constant expression?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM