X is not a valid template argument for 'const char*' because it is not the address of a variable

464 Views Asked by At

I'm trying to use the resources of a temporary class object as a template parameter. But apparently this doesn't work:

godbolt

#include <iostream>

constexpr size_t size(const char* s)
{
    int i = 0;
    while(*s!=0) {
        ++i;
        ++s;
    }
    return i;
}

template <const char* S>
struct string_struct
{
    constexpr string_struct() {
        for (int i=0; i < size(S); ++i) {
            buf_[i] = S[i];
        }
    }
    constexpr const char* get() {
        return buf_;
    }
    char buf_[size(S)] = {0};
};

constexpr const char some_chars[] = "100";

constexpr auto compose_string()
{
    string_struct<some_chars> other_str{};
    return string_struct<other_str.get()>;
}

int main()
{
    compose_string();
}

gcc 12.1 complains:

<source>: In function 'constexpr auto compose_string()':
<source>:32:41: error: 'other_str.string_struct<(& some_chars)>::get()' is not a valid template argument for 'const char*' because it is not the address of a variable
   32 |     return string_struct<other_str.get()>;
      |                                         ^
<source>:29:16: error: invalid return type 'auto' of 'constexpr' function 'constexpr auto compose_string()'
   29 | constexpr auto compose_string()
      |   

Of course this is a contrived example. What I actually want to do is extend an enhanced version of string_struct recursively. But how can I use its resources for template instantiation? And if that is somehow possible, how do I deduce the return type of a function that returns string_structs (and in the recursive case a string_struct, that is instantiated with another string_struct, that is instantiated with another sstring_struct...)?

Is it even possible?

0

There are 0 best solutions below