I was playing with strings in templates. I read some interesting blogs and started playing with code.
In the next example, I was able to pass a string literal in a template argument:
#include <algorithm>
#include <iostream>
template<size_t N>
struct StringLiteral {
    constexpr StringLiteral(const char (&str)[N]) {
        // commenting this makes the program to not compile
        std::copy_n(str, N, value);
    }
    constexpr size_t size() const
    {
        return N;
    }
    // changing N to literal, such as 10, makes the program to not compile
    char value[N];
};
template<StringLiteral lit>
void Print() {
    static constexpr auto size = lit.size();
    static constexpr auto contents = lit.value;
    std::cout << "Size: " << size << ", Contents: " << contents << std::endl;
}
int main()
{
    Print<"abc">();
}
Godbolt Link
In this example, I'm passing a string to Print by a template parameter, and it will print the size and value.  So far so good.
However, I'm using some features that I don't fully understand, that's probably why I'm so confused.
std::copy_n(), it doesn't compile. That was very surprising because that code is inside the constructor, N was deduced just before, so I'm not sure why copy_n had these implications.char value[N] to char value[10] also makes the program invalid. 10 is a literal, so I was expecting the compiler would be able to deduce it without a problem.Could you clarify what's going on?
Both errors are caused by value remaining partially uninitialized. Adding {} to zero all elements by default is one way to solve this: char value[N]{};.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With