【问题标题】:How to initialize a const string as the concatenation of two strings during compilation time?如何在编译期间将 const 字符串初始化为两个字符串的串联?
【发布时间】:2023-03-26 20:05:02
【问题描述】:

以下代码在编译期间初始化两个 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

【问题讨论】:

标签: c++ string c++11 constexpr


【解决方案1】:

您不能实例化 constexpr std::string。

cppreference states,对于 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;
};

也许this answer 可以进一步帮助您。

【讨论】:

    【解决方案2】:

    我不相信 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");
    

    【讨论】:

    • 您的CES 省略了空终止符,这将导致非字符串。
    • @nneonneo 我同意。它们实际上更像是字符数组而不是字符串。但是,正如您可能已经发现的那样,只需进行一些小的更改即可使它们以空值终止。
    猜你喜欢
    • 2013-12-23
    • 2012-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多