'template instantiation via a function parameter in C++?

I have a class template which takes a compile time string as the template parameter. For example


template<size_t Size>
struct Buffer
{
    char buffer[Size] = {0};
    consteval Buffer(const char (&arr) [ Size ])
    {
        for(size_t i = 0; i != Size; ++i) buffer[i] = arr[i]; 
    }

};
// this is the template which I want to instantiate with a function parameter
template<Buffer buffer>
struct interned_buffer
{
    consteval static const char* first() { return &buffer.first; }
};

constexpr const char* example = "hello";

struct MyStruct
{
    template<size_t Size>
    consteval MyStruct(const char (&arr) [ Size ] ) requires(std::is_constant_evaluated())
    {
        if constexpr(5 > Size)
            first = example;
        else
            first = interned_buffer<arr>::first();
            // error 'arr' is not a constant expression :(
    }
private:
    const char* first = nullptr;
};

constexpr static MyStruct s = "hello";

This is of course not real world code, this is a small example (the real code is way more complex and irrelevant). TLDR: I want to instantiate a template from a FUNCTION argument which is known in compile time.



Solution 1:[1]

If the only problem is that arr is not constexpr, pass it via template

Since, constructors can not be called with diamond brackets, you will need to create some wrapper and dispatch it there, like this

template <auto buffer>
struct bufferHolder
{
    constexpr static auto buf = buffer;
};

struct MyStruct
{
    template<auto buffer>
    consteval MyStruct(bufferHolder<buffer>)
    {
        if constexpr(5 > std::size(buffer.buffer))
            first = example;
        else
            first = interned_buffer<buffer>::first();
    }
private:
    const char* first = nullptr;
};

constexpr static MyStruct s = bufferHolder<Buffer{"hello"}>{};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1