如何在编译期间将const字符串初始化为两个字符串的连接

How to initialize a const string as the concatenation of two strings during compilation time?

本文关键字:字符串 两个 连接 初始化 编译 const      更新时间:2023-10-16

下面的代码在编译时初始化了两个const字符串:

class Test
{
public:
    static constexpr const char* LOS = "Los ";
    static constexpr const char* ANGELES = "Angeles";
};

如何创建另一个常量字符串(const char*const std::string)作为两个常量字符串的连接?添加以下行

static constexpr const std::string LOS_ANGELES = std::string(LOS).append(ANGELES);

发出错误:

error: the type ‘const string {aka const std::basic_string<char>}’ of constexpr variable ‘Test::LOS_ANGELES’ is not literal

不能实例化constexpr std::string

cppreference声明,对于c++ 11, constexpr变量要求其类型为LiteralType。LiteralType有一个平凡的析构函数,但是std::string的析构函数不是平凡的。

可以使用宏。这是丑陋的,但它工作。

#define MLOS "Los "
#define MANGELES "Angeles"
class Test
{
public:
    static constexpr const char* LOS = MLOS;
    static constexpr const char* ANGELES = MANGELES;
    static constexpr const char* LOSANGELES = MLOS MANGELES;
};

也许这个答案对你有帮助。

我不相信std::string的构造函数是constexpr,所以我认为这是不可能的。但是,您可以模拟它:

template<int LENGTH>
struct CES {
  static constexpr auto size = LENGTH;
  char data[LENGTH];
};
template<int N>
constexpr auto make_ces(const char (&v)[N]) {
  CES<N-1> result {};
  for (int i = 0; i < N-1; ++i) {
    result.data[i] = v[i];
  }
  return result;
}
template<int L1, int L2>
constexpr CES<L1+L2> operator+(const CES<L1>& x, const CES<L2>& y) {
  CES<L1+L2> result{};
  for (int i = 0; i < L1; ++i) {
    result.data[i] = x.data[i];
  }
  for (int i = 0; i < L2; ++i) {
    result.data[L1+i] = y.data[i];
  }
  return result;
}
constexpr auto LOS = make_ces("Los");
constexpr auto ANGELES = make_ces("Angeles");
constexpr auto LOS_ANGELES = LOS + ANGELES;
static_assert(LOS_ANGELES.data[2] == 's', "ok");