简体   繁体   English

如何创建带有前置长度字节的编译时常量字符串?

[英]How to create compile-time constant string with prepended length byte?

I have some old code that uses #define to, um, define some string literals, eg我有一些旧代码使用#define来定义一些字符串文字,例如

#define FredString "\004FRED"

That I would like to update to avoid using #define .我想更新以避免使用#define Closest I get is something like the following:我得到的最接近的是以下内容:

static constexpr char* FSraw= "FRED";
static constexpr char FSlen= (char)(sizeof(FSraw) - 1);
static constexpr char* FredString= FSlen FSraw;

but the compiler seems unhappy on the third line.但编译器似乎对第三行不满意。

What would be the best way to construct such a string at compile time?在编译时构造这样一个字符串的最佳方法是什么? Obviously I could still explicitly encode the length, but also obviously, that's more error prone.显然我仍然可以显式编码长度,但很明显,这更容易出错。

Looking for solutions for C++17 or earlier.寻找 C++17 或更早版本的解决方案。

template <std::size_t N>
constexpr std::array<char, N+1> AddLenPrefix(const char (&str)[N])
{
    std::array<char, N+1> ret{};
    ret[0] = N-1; // Exclude the '\0'.
    for (std::size_t i = 0; i < N; i++)
        ret[i+1] = str[i];
    return ret;
}

static constexpr auto FredString = AddLenPrefix("FRED");

You can also have something like:你也可以有类似的东西:

#include <string_view>
#include <utility>

template <std::string_view const& S, typename>
struct prepend_length_impl;

template <std::string_view const& S, std::size_t ... Is>
struct prepend_length_impl<S, std::index_sequence<Is...>> {
    static constexpr const char value[]{ (sizeof...(Is) + '0'), S[Is]..., 0 };
};

template <std::string_view const& S>
struct prepend_length {
    static constexpr std::string_view value =
        prepend_length_impl<S, std::make_index_sequence<S.size()>>::value;
};

and then use it like:然后像这样使用它:

static constexpr std::string_view raw = "fred";
static constexpr std::string_view fred = prepend_length<raw>::value; // "4fred"

DEMO 演示

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM