I am currently facing a template metaprogramming problem that has to do with string literals and type erasure.
The problem is the following. Let's consider the following code:
template <static_string name> struct id {
using type = decltype(name);
};
static_assert(std::is_same_v<
typename id<"Hey">::type,
typename id<"Hello!">::type
>)
QUESTION: How to design a class static_string
which would "erase" as part of its type the character type and its length so that the static_assert
above would not fail?
CodePudding user response:
Short version: you cannot.
The type of non-type template parameters (NTTPs) are required to provide "structural equality". This means that two objects of such a type are equal (as far as template instantiation is concerned) iff the byte sequences stored within each object are equal.
If you have a string type that is intended to be usable as an NTTP, it must therefore store the sequence of characters within itself. Which means it's going to be stored as an array of some kind. The type of those characters and the number of characters stored is part of the definition of that type.
Your static_string
type could have a variable size. You would do this by giving them a fixed internal buffer size and have a constructor that computes the length of the given string and stores it internally as well. However, such a type cannot have a variable character type. That's just part of the type's components.
CodePudding user response:
No problem:
struct static_string {
constexpr static_string(char const*) { }
};