Home > Enterprise >  C 20 concept matching string literal
C 20 concept matching string literal

Time:12-27

In C 20 it is possible to write a wrapper class which only accepts string literals.

struct string_literal
{
    template<size_t N>
    consteval Wrapper(char const (&s)[N]) : p(s) {}

    char const* p;
};
void takes_literal(string_literal lit) {
  // use lit.p here
}

from OP's own answer here https://stackoverflow.com/a/74922953


Is it also possible to write a concept that only matches string literals?

CodePudding user response:

A char const* which points into a string literal is virtually no different from any other char const*. The fact that a literal starts its life as an array is irrelevant, as non-literal character arrays can also be created. To my knowledge, there is exactly one difference: pointers to string literals cannot be used as non-type template parameters.

That's not particularly helpful. Even if we were restricted to compile-time code execution, you can get non-literal char const*s which also cannot be used as NTTPs (by creating a std::string, which can now be done at compile-time. You can call constexpr functions on string::c_strs pointer, but you can't use the result as an NTTP).

The best you can do is to create a user-defined literal operator that returns your string_literal object. You can make it so that only this literal operator can construct such a type (besides copying, of course). But even then, they can call your operator"" directly with a non-literal, and there is nothing you can do about it.

Instead, you should re-evaluate why you need to know if it is a string literal specifically.

CodePudding user response:

Whereas const char(&)[N] isn't necessary a string literal, you might create concept to match const char(&)[N]:

template <typename T>
struct is_str_literal_impl : std::false_type{};

template <std::size_t N>
struct is_str_literal_impl<const char[N]> : std::true_type{};

template <typename T>
concept concept_str_literal = is_str_literal_impl<T>::value;

void takes_literal(concept_str_literal auto&  lit) {
  // use lit.p here
}

Demo

  • Related