First if we want to create a new type for a template parameter we need to create a structural type, this means we cannot use private members or functions.
Our compile time string will contain our string and it will not use new
or delete
, it can be possible to use new
and delete
in a constexpr
function block but in this case we cannot hold dynamic memory in a lifetime constexpr
variable.
I wrote the following template which it holds a fixed string, and can be used with templates as well.
#include <algorithm> template<std::size_t N> struct CompTimeStr { char data[N] {}; consteval CompTimeStr(const char (&str)[N]) { std::copy_n(str, N, data); } consteval bool operator==(const CompTimeStr<N> str) const { return std::equal(str.data, str.data+N, data); } template<std::size_t N2> consteval bool operator==(const CompTimeStr<N2> s) const { return false; } template<std::size_t N2> consteval CompTimeStr<N+N2-1> operator+(const CompTimeStr<N2> str) const { char newchar[N+N2-1] {}; std::copy_n(data, N-1, newchar); std::copy_n(str.data, N2, newchar+N-1); return newchar; } consteval char operator[](std::size_t n) const { return data[n]; } consteval std::size_t size() const { return N-1; } }; template<std::size_t s1, std::size_t s2> consteval auto operator+(CompTimeStr<s1> fs, const char (&str) [s2]) { return fs + CompTimeStr<s2>(str); } template<std::size_t s1, std::size_t s2> consteval auto operator+(const char (&str) [s2], CompTimeStr<s1> fs) { return CompTimeStr<s2>(str) + fs; } template<std::size_t s1, std::size_t s2> consteval auto operator==(CompTimeStr<s1> fs, const char (&str) [s2]) { return fs == CompTimeStr<s2>(str); } template<std::size_t s1, std::size_t s2> consteval auto operator==(const char (&str) [s2], CompTimeStr<s1> fs) { return CompTimeStr<s2>(str) == fs; }
This template will let us to operate over strings at compile time, we can compare and concatenate them at compile time.
Each time we concatenate strings it will return a new CompTimeStr<N>
.
This lets us a world of possibilities, we could even create a search function to find specific words in our string and its position.
Usage example
This is a basic usage of CompTimeStr<N>
#include <iostream> template<CompTimeStr str> constexpr auto addBar() { return str + " bar"; } constexpr CompTimeStr str = addBar<"foo">(); int main() { std::cout << str.data << std::endl; std::cout << std::boolalpha << (str == "foo bar") << std::endl; }
The output will be:
foo bar true
If we look at the non-optimized assembly output, we will find this:
We can see foo bar
concatenated at compile time and (str == "foo bar")
condition precalculated as well.
Top comments (1)
Quite a well written article @sgf4
We are in the process of updating some books under our C++ portfolio. Over the next few weeks I am conducting a research in the C++ space to discover the top issues that C++ developers/programmers/experts like yourself are dealing with. We are reaching out to users to understand their needs/expectations and what they are looking for in C++ space.
After reviewing your profile, I believe that you could help me to gain a thorough understanding of what is working and not working for C++ developers like you.
Would you be happy to join me for a 10-minute call to discuss on how we can improvise our C++ books? Your inputs will be critical for us to bring forward a top-notch product for the C++ enthusiasts.