2

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?

glades
  • 3,778
  • 1
  • 12
  • 34
  • I think the problem is that you are trying to instantiate the templates (compile-time) using something that is only known at runtime (object addresses). But on the other hand, I am not sure I understand what you are trying to achieve. What is the end result that you want? – Krzysiek Karbowiak Jun 09 '22 at 08:33
  • 1
    @KrzysiekKarbowiak I want to save a compile-time composed string into the binary of the executable. The compile-time version of the class should also have an address no? – glades Jun 09 '22 at 12:29
  • Is this string used anywhere? If not, it may very well get removed by optimisations if you have those enabled. And no, "compile-time version of the class" does not have an address, as it is a type. An address is a property of an object of that type. Objects are created in runtime (e.g. on the stack or on the heap in case of dynamic allocation). At least this is the situation in C++17 which you mention. Later standard versions allow more things to happen during compilation. – Krzysiek Karbowiak Jun 09 '22 at 12:51
  • @KrzysiekKarbowiak That is true, however I think that at compile time when the constexpr is evaluated, the object needs a space to temporarily until the expression is fully evaluated right? That's where the string_struct.get() function grabs the resources from - or should. – glades Jun 09 '22 at 15:09

0 Answers0