मेरे पास कुछ पुराना कोड है जो #define का उपयोग करता है, उम, कुछ स्ट्रिंग अक्षर परिभाषित करता है, उदा।

#define FredString "\004FRED"

#define का उपयोग करने से बचने के लिए मैं इसे अपडेट करना चाहूंगा। मुझे जो निकटतम मिलता है वह निम्न जैसा कुछ है:

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

लेकिन संकलक तीसरी पंक्ति पर नाखुश लगता है।

संकलन समय पर ऐसी स्ट्रिंग बनाने का सबसे अच्छा तरीका क्या होगा? जाहिर है, मैं अभी भी लंबाई को स्पष्ट रूप से एन्कोड कर सकता हूं, लेकिन जाहिर है, यह अधिक त्रुटि प्रवण है।

सी ++ 17 या इससे पहले के समाधान खोज रहे हैं।

1
tastewar 8 पद 2020, 21:44

2 जवाब

सबसे बढ़िया उत्तर
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");
5
Remy Lebeau 8 पद 2020, 22:32

आपके पास कुछ ऐसा भी हो सकता है:

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

और फिर इसे इस तरह इस्तेमाल करें:

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

डेमो

0
NutCracker 9 पद 2020, 13:41