It has happened to many people, and it happened to me. I got stuck playing with compile time strings in C++.
I decided to take the apparently unusable approach: using template <char...>
classes.
This is what I came up with, it is very common, nothing special, and also it does not work.
template <char... chars> class string
{
public:
static constexpr const char value[] = {chars...};
constexpr string()
{
}
constexpr operator decltype(value) & () const
{
return value;
}
};
template <char... chars> constexpr const char string <chars...> :: value[];
My idea was making a string
instance constexpr
constructible and exposing some kind of constexpr casting so that it would provide its content.
Now, if I do
static constexpr const char x[] = "ciao";
template <const char * str> void print()
{
std :: cout << str << std :: endl;
}
print <x> ();
This works and says ciao
. I get ciao
also if I do
std :: cout << string <'c', 'i', 'a', 'o'> {} << std :: endl;
or
print <string <'c', 'i', 'a', 'o', '\0'> :: value> ();
But when I do
print <string <'c', 'i', 'a', 'o', '\0'> {}> ();
I get: No matching function for call to print
.
I am definitely missing something. Is it unfeasible to do what I am trying to do? Making an instance do a constexpr cast to somehow return value
? If that worked, I would be able to easily make operators and string manipulation at compile time, the "only" downside being the ultra-boring 'i', 'n', 'i', 't', 'i', 'a', 'l', 'i', 'z', 'a', 't', 'i', 'o', 'n'
.
Further experiments
I did another experiment that works perfectly.
template <char... chars> class string
{
public:
constexpr string()
{
}
constexpr operator size_t () const
{
return sizeof...(chars);
}
};
template <size_t length> void print()
{
std :: cout << length << std :: endl;
}
print <string <'c', 'i', 'a', 'o'> {}> ();
And it prints out a pretty 4
.